我试图执行非等值连接,然后在j
中返回值列表,其中某些值取决于j表达式中的先前值。在我的示例中,i_val
取决于是否知道i_min
,但是我想返回两个值(2列值的行,加上by
列)
library(data.table)
DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9, date = seq(as.Date("2019-03-15"), by ="days", length.out = 9))
DTI <- data.table(date = as.Date(c("2019-03-16", "2019-03-21")), size = 55, len = c(3, 4), len2 = c(5, 5))
expr2 <- quote({
i_min <- min(which(y > len));
list(i_min = i_min, i_val =y[i_min])
})
DT[DTI, eval(expr2),
on = .(date > date),
by = .EACHI, allow.cartesian = TRUE, verbose = TRUE]
我得到了预期的结果,但是冗长的消息似乎表明这并不有效,因为我正在返回一个命名列表。
检测到非设备联接运算符... forder花了...经过0.000s(0.000s cpu) 生成非设备组ID ...已用0.000s(0.000s cpu)完成 找到1个非马戏团... 将双列i.'date'强制转换为整数以匹配x.'date'的类型。请避免强制使用效率。 开始bmerge ...完成0.000s(0.000s cpu) 检测到j使用以下列:y,len lapply优化已启用,j不变为'{i_min <-min(which(y> len))list(i_min = i_min,i_val = y [i_min])}'' 旧的均值优化功能已启用,j保持不变。 制作每个组并运行j(GForce FALSE)... j的结果是一个命名列表。为每个组一遍又一遍地创建相同的名称是非常低效的。当j = list(...)时,为了提高效率,会在分组完成后检测,删除并放回任何名称。例如,使用j = transform()可以防止加速(考虑更改为:=)。此消息将来可能会升级为警告。 memcpy连续组2组花费0.000s eval(j)2次通话花费0.000s 过去0.000s(0.000s cpu)
正确的输出:
date i_min i_val
1: 2019-03-16 1 6
2: 2019-03-21 2 6
是的,j正在返回一个命名列表(list(i_min = i_min, i_val =y[i_min])
)。有没有更有效的方法来执行此查询?
我不知道如何编写语法来使j
高效地执行此操作,或者...我只是不明白警告,“ j的结果是一个命名列表。为每个组一遍又一遍地创建相同的名称。当j = list(...)时,会在分组完成后检测,删除并放回任何名称,以提高效率。”
我的实际联接表内存很大,因此,如果有更理想的方法,我很想知道