我正在尝试简化此xterm
两阶段过程,该过程对数字和字符变量起作用。例如。 - 获取每个数字变量的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
以从.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
是否有更简单的结构可以绕过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
或加入的嵌套?我觉得我忽略了一些基本的东西。
答案 0 :(得分:9)
data.table 中的j
- 参数(故意)非常灵活。我们需要记住的是:
只要
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
在这里,由于list()
返回长度= 1的向量,我没有用textvar[1L]
包装第一个表达式。即,identical(c(1, list(2, 3)), c(list(1), list(2,3)))
是TRUE
。< / p>
请注意,这只能来自v1.9.7
。该错误最近刚刚在当前的开发版本中得到修复。