R data.table:(动态)前瞻性交叉连接
R data.table: (dynamic) forward looking Cross-Joins
我想知道 data.table 中的 CJ() 方法是否有一个选项来获取由评估条件而不是 运行 完整交叉连接形成的向量。
数据
library(data.table)
df<-data.table(
ID=c(18L, 18L, 18L, 46L, 74L, 74L, 165L, 165L),
cat=c(1300L, 1320L, 1325L, 1300L, 1300L, 1325L, 1300L, 1325L),
low=c(24.625, 16.250, 14.500, 43.625, 58.250, 45.375, 90.750, 77.875),
high=c(26.625, 17.500, 15.500, 45.625, 60.000, 47.375, 92.750, 79.875)
)
df
ID cat low high
1: 18 1300 24.625 26.625
2: 18 1320 16.250 17.500
3: 18 1325 14.500 15.500
4: 46 1300 43.625 45.625
5: 74 1300 58.250 60.000
6: 74 1325 45.375 47.375
7: 165 1300 90.750 92.750
8: 165 1325 77.875 79.875
在这里,我总共有 4 个不同项目(ID 18、46、74 和 165)的 8 个观察值。每个项目都记录在几个类别中(cat 1300、1320、1325)并进行了两次测量(低和高)。
期望输出
我现在想创建一个 table,将每个项目 (ID) 的每个类别 (cat) 的低值与更大类别的所有高值结合起来33=] 通过交叉连接。因此,我想要的输出看起来像
ID cat cat_large low high
1: 18 1300 1320 24.625 17.500
2: 18 1300 1325 24.625 15.500
3: 18 1320 1325 16.250 15.500
4: 74 1300 1325 58.250 47.375
5: 165 1300 1325 90.750 79.875
我在其中添加了 cat_high 以指示在 low/high 中加入了哪两个类别。
不幸的是,我找不到正确的方法来修改我的完整交叉连接 df[,CJ(low=low,high=high),by=.(ID)]
,使其表现得像这样。我很感激任何 help/hints.
我认为您可以通过非等连接中的 .EACHI
执行此操作。然后,您可以使用 i.
前缀到 select 其中 table 从以下位置获取输出变量:
df[, c(.SD,.(larger_cat=cat))][
df, on=.(ID==ID, cat > cat), .(larger_cat, low=i.low, high), by=.EACHI, nomatch=0
]
# ID cat larger_cat low high
#1: 18 1300 1320 24.625 17.500
#2: 18 1300 1325 24.625 15.500
#3: 18 1320 1325 16.250 15.500
#4: 74 1300 1325 58.250 47.375
#5: 165 1300 1325 90.750 79.875
不是 dplyr
解决方案,但我认为以下是另一种选择。
library(dplyr)
library(tidyr)
df2 <- df %>%
group_by(ID) %>%
complete(low, high) %>%
mutate(cat_large = cat) %>%
group_by(ID, low) %>%
mutate(cat = na.omit(cat)) %>%
group_by(ID, high) %>%
mutate(cat_large = na.omit(cat_large)) %>%
filter(low > high) %>%
arrange(ID, desc(low), desc(high)) %>%
select(ID, cat, cat_large, low, high)
df2
# A tibble: 5 x 5
# Groups: ID, high [4]
ID cat cat_large low high
<int> <int> <int> <dbl> <dbl>
1 18 1300 1320 24.625 17.500
2 18 1300 1325 24.625 15.500
3 18 1320 1325 16.250 15.500
4 74 1300 1325 58.250 47.375
5 165 1300 1325 90.750 79.875
一种方式:
df[, c(
CJ(cat = cat, lcat = cat, sorted = FALSE),
CJ(low = low, high = high, sorted = FALSE)
), by=ID][lcat > cat]
ID cat lcat low high
1: 18 1300 1320 24.625 17.500
2: 18 1300 1325 24.625 15.500
3: 18 1320 1325 16.250 15.500
4: 74 1300 1325 58.250 47.375
5: 165 1300 1325 90.750 79.875
我想知道 data.table 中的 CJ() 方法是否有一个选项来获取由评估条件而不是 运行 完整交叉连接形成的向量。
数据
library(data.table)
df<-data.table(
ID=c(18L, 18L, 18L, 46L, 74L, 74L, 165L, 165L),
cat=c(1300L, 1320L, 1325L, 1300L, 1300L, 1325L, 1300L, 1325L),
low=c(24.625, 16.250, 14.500, 43.625, 58.250, 45.375, 90.750, 77.875),
high=c(26.625, 17.500, 15.500, 45.625, 60.000, 47.375, 92.750, 79.875)
)
df
ID cat low high
1: 18 1300 24.625 26.625
2: 18 1320 16.250 17.500
3: 18 1325 14.500 15.500
4: 46 1300 43.625 45.625
5: 74 1300 58.250 60.000
6: 74 1325 45.375 47.375
7: 165 1300 90.750 92.750
8: 165 1325 77.875 79.875
在这里,我总共有 4 个不同项目(ID 18、46、74 和 165)的 8 个观察值。每个项目都记录在几个类别中(cat 1300、1320、1325)并进行了两次测量(低和高)。
期望输出
我现在想创建一个 table,将每个项目 (ID) 的每个类别 (cat) 的低值与更大类别的所有高值结合起来33=] 通过交叉连接。因此,我想要的输出看起来像
ID cat cat_large low high
1: 18 1300 1320 24.625 17.500
2: 18 1300 1325 24.625 15.500
3: 18 1320 1325 16.250 15.500
4: 74 1300 1325 58.250 47.375
5: 165 1300 1325 90.750 79.875
我在其中添加了 cat_high 以指示在 low/high 中加入了哪两个类别。
不幸的是,我找不到正确的方法来修改我的完整交叉连接 df[,CJ(low=low,high=high),by=.(ID)]
,使其表现得像这样。我很感激任何 help/hints.
我认为您可以通过非等连接中的 .EACHI
执行此操作。然后,您可以使用 i.
前缀到 select 其中 table 从以下位置获取输出变量:
df[, c(.SD,.(larger_cat=cat))][
df, on=.(ID==ID, cat > cat), .(larger_cat, low=i.low, high), by=.EACHI, nomatch=0
]
# ID cat larger_cat low high
#1: 18 1300 1320 24.625 17.500
#2: 18 1300 1325 24.625 15.500
#3: 18 1320 1325 16.250 15.500
#4: 74 1300 1325 58.250 47.375
#5: 165 1300 1325 90.750 79.875
不是 dplyr
解决方案,但我认为以下是另一种选择。
library(dplyr)
library(tidyr)
df2 <- df %>%
group_by(ID) %>%
complete(low, high) %>%
mutate(cat_large = cat) %>%
group_by(ID, low) %>%
mutate(cat = na.omit(cat)) %>%
group_by(ID, high) %>%
mutate(cat_large = na.omit(cat_large)) %>%
filter(low > high) %>%
arrange(ID, desc(low), desc(high)) %>%
select(ID, cat, cat_large, low, high)
df2
# A tibble: 5 x 5
# Groups: ID, high [4]
ID cat cat_large low high
<int> <int> <int> <dbl> <dbl>
1 18 1300 1320 24.625 17.500
2 18 1300 1325 24.625 15.500
3 18 1320 1325 16.250 15.500
4 74 1300 1325 58.250 47.375
5 165 1300 1325 90.750 79.875
一种方式:
df[, c(
CJ(cat = cat, lcat = cat, sorted = FALSE),
CJ(low = low, high = high, sorted = FALSE)
), by=ID][lcat > cat]
ID cat lcat low high
1: 18 1300 1320 24.625 17.500
2: 18 1300 1325 24.625 15.500
3: 18 1320 1325 16.250 15.500
4: 74 1300 1325 58.250 47.375
5: 165 1300 1325 90.750 79.875