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