the*_*ail 8 join r lapply data.table
我正在尝试简化这个data.table对数字和字符变量起作用的两阶段过程.例如 - 取第一个元素textvar和sum每个数字变量.考虑这个小例子:
library(data.table)
dt <- data.table(grpvar=letters[c(1,1,2)], textvar=c("one","two","one"),
numvar=1:3, othernum=2:4)
dt
# grpvar textvar numvar othernum
#1: a one 1 2
#2: a two 2 3
#3: b one 3 4
Run Code Online (Sandbox Code Playgroud)
现在我的第一个想法是嵌套.SD以将一个变量从lapply调用中删除,但我认为这有点复杂:
dt[, c(textvar=textvar[1], .SD[, lapply(.SD, sum), .SDcols=-c("textvar")]), by=grpvar]
# grpvar textvar numvar othernum
#1: a one 3 5
#2: b one 3 4
Run Code Online (Sandbox Code Playgroud)
然后我想也许我可以单独分组并加入它们,但这似乎更糟糕:
dt[, .(textvar=textvar[1]), by=grpvar][
dt[, lapply(.SD, sum), by=grpvar, .SDcols=-c("textvar")], on="grpvar"
]
# grpvar textvar numvar othernum
#1: a one 3 5
#2: b one 3 4
Run Code Online (Sandbox Code Playgroud)
是否有更简单的结构可以绕过嵌套.SD或连接?我觉得我忽略了一些基本的东西.
将j在-argument data.table是(故意)相当灵活.我们需要记住的是:
只要
j返回一个列表,列表中的每个元素都将成为结果data.table中的一列.
使用的事实c(list, list)是list,我们可以构建表达如下:
dt[, c(textvar = textvar[1L], lapply(.SD, sum)), # select/compute all cols necessary
.SDcols = numvar:othernum, # provide .SD's columns
by = grpvar] # group by 'grpvar'
# grpvar textvar numvar othernum
# 1: a one 3 5
# 2: b one 3 4
Run Code Online (Sandbox Code Playgroud)
在这里,我没有包装第一个表达式,list()因为textvar[1L]返回一个长度= 1的向量..即,identical(c(1, list(2, 3)), c(list(1), list(2,3)))是TRUE.
请注意,这只能来自v1.9.7.该错误最近刚刚在当前的开发版本中得到修复.