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

我正在尝试简化这个data.table两阶段过程,它同时作用于数字和字符变量.例如. – 获取textvar的第一个元素并对每个数字变量求和.考虑这个小例子:
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[,by=grpvar,.SDcols=-c("textvar")],on="grpvar" 
]
#   grpvar textvar numvar othernum
#1:      a     one      3        5
#2:      b     one      3        4

是否有更简单的结构可以绕过.SD或加入的嵌套?我觉得我忽略了一些基本的东西.

解决方法

data.table中的j参数(故意)非常灵活.我们需要记住的是:

As long as j returns a list,each element of the list will become a column in the resulting data.table.

使用c(list,list)是一个列表的事实,我们可以构造如下表达式:

dt[,c(textvar = textvar[1L],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()包装第一个表达式,因为textvar [1L]返回一个length = 1的向量..即,相同(c(1,list(2,3)),c(list(1),3)))为TRUE.

请注意,这只能从v1.9.7开始.最近在当前开发版本中修复了该错误.

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 &#39;EastRiver&#39; 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...