如何在data.table中实现类似dplyr group_by的混合列分组?
在data.table中实现混合非连续列与连续列的分组
问题背景
dplyr的group_by功能支持用冒号(:)快速选择连续列,非连续列用逗号分隔组合,但在data.table中直接使用by = .(a, c:d)的写法会报错,无法实现预期分组。示例代码如下:
library(data.table) # 创建示例data.table dt <- data.table(a = c("A", "A", "B", "B"), b = c(1, 2, 3, 4), c = c(5, 6, 7, 8), d = c(9, 10, 11, 12)) # 尝试按a、c到d的连续列分组(此写法会报错) dt[, .(sum(b)), by = .(a, c:d)]
可行解决方案
方法1:手动构造分组列名向量
通过列名匹配生成连续列的名称向量,再与非连续列组合后传入by参数:
# 提取c到d的连续列名 range_cols <- names(dt)[which(names(dt) == "c"):which(names(dt) == "d")] # 组合非连续列与连续列 group_cols <- c("a", range_cols) # 执行分组计算 dt[, .(sum(b)), by = group_cols]
方法2:利用eval()和parse()解析列范围表达式
直接解析包含列范围的表达式,在data.table的上下文环境中执行:
dt[, .(sum(b)), by = eval(parse(text = "c(a, c:d)"))]
方法3:使用..符号传递列范围变量
先在外部定义列范围,再通过..符号引用并组合非连续列:
range_cols <- "c:d" dt[, .(sum(b)), by = c("a", ..range_cols)]
以上三种方法都能实现和dplyr中group_by(a, c:d)相同的分组效果,可根据实际场景选择使用。
内容的提问来源于stack exchange,提问作者some
相关产品推荐
相关产品推荐

