data.table分别对数字和文本变量进行分组

时间:2016-09-01 00:14:59

标签: r join data.table lapply

我正在尝试简化此xterm两阶段过程,该过程对数字和字符变量起作用。例如。 - 获取每个数字变量的data.tabletextvar的第一个元素。考虑这个小例子:

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 或加入的嵌套?我觉得我忽略了一些基本的东西。

1 个答案:

答案 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。该错误最近刚刚在当前的开发版本中得到修复。