You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在data.table中使用dplyr/across速度慢,求兼顾速度与便捷的方案

问题:兼顾dplyr便捷性与data.table性能的分组汇总方法

使用dplyr的across()函数按字符型变量分组、汇总数值型变量时,无需手动指定变量名,非常便捷。但如果把这套逻辑用在data.table对象上,运行速度会明显变慢,和操作普通data.frame差不多。有没有办法既能保留这种自动识别变量的便捷性,又不损失data.table的高性能?

原代码示例:

library(data.table)
library(dplyr)
test_data <- data.table(x=c('a','b','c','a','b','c'),y=c('d','e','f','d','e','f'),a=c(1:6),b=c(1,7,NA,3,5,6),c=c(NA,3,NA,4,7,8))
test_data %>% group_by(across(where(is.character))) %>% 
  summarise(across(where(is.number),function(x) sum(x,na.rm=TRUE)))

方案1:data.table原生语法+自动变量筛选

先自动识别并提取分组变量(字符型)和汇总变量(数值型),再用data.table原生语法执行,既不用手动写变量名,又能发挥data.table的性能优势。

代码示例:

library(data.table)

test_data <- data.table(x=c('a','b','c','a','b','c'),y=c('d','e','f','d','e','f'),a=c(1:6),b=c(1,7,NA,3,5,6),c=c(NA,3,NA,4,7,8))

# 自动筛选分组变量和汇总变量
group_vars <- names(test_data)[sapply(test_data, is.character)]
sum_vars <- names(test_data)[sapply(test_data, is.numeric)]

# data.table原生分组汇总
test_data[, lapply(.SD, sum, na.rm = TRUE), by = group_vars, .SDcols = sum_vars]

方案2:用dtplyr适配dplyr语法到data.table

dtplyr是dplyr的data.table适配器,允许你写熟悉的dplyr风格代码,底层会自动转换成data.table原生语法执行,兼顾便捷性和性能。

代码示例:

library(data.table)
library(dtplyr)
library(dplyr, warn.conflicts = FALSE)

test_data <- data.table(x=c('a','b','c','a','b','c'),y=c('d','e','f','d','e','f'),a=c(1:6),b=c(1,7,NA,3,5,6),c=c(NA,3,NA,4,7,8))

# 用lazy_dt包装后使用dplyr语法
test_data %>%
  lazy_dt() %>%
  group_by(across(where(is.character))) %>%
  summarise(across(where(is.numeric), ~sum(.x, na.rm = TRUE))) %>%
  as.data.table()

方案3:封装自定义函数简化重复操作

如果需要频繁执行这类分组汇总,可以把变量筛选和data.table操作封装成函数,调用时一步到位:

代码示例:

library(data.table)

# 自定义分组汇总函数
sum_by_char_groups <- function(dt) {
  group_vars <- names(dt)[sapply(dt, is.character)]
  sum_vars <- names(dt)[sapply(dt, is.numeric)]
  return(dt[, lapply(.SD, sum, na.rm = TRUE), by = group_vars, .SDcols = sum_vars])
}

# 调用函数
test_data <- data.table(x=c('a','b','c','a','b','c'),y=c('d','e','f','d','e','f'),a=c(1:6),b=c(1,7,NA,3,5,6),c=c(NA,3,NA,4,7,8))
sum_by_char_groups(test_data)

内容的提问来源于stack exchange,提问作者anderwyang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:10:17