使用{data.table}编程时如何通过函数参数自定义新列名?
data.table 汇总场景动态指定列名的解决方案
核心原因
data.table的.()汇总语法中,=左侧默认会被识别为字面量列名,不会解析对应变量的实际值;而:=原地赋值语法专门做了动态命名的适配,支持{变量名}的写法,因此两种场景表现不一致。
三种常用实现方案
方案1:setNames 封装(最简洁,兼容所有版本)
.()本质是list()的语法糖,直接用setNames()给返回的列表设置动态名称即可:
my_wrapper <- function(new_colname_of_choice) { mtcars %>% as.data.table() %>% .[, setNames(.(max(mpg)), new_colname_of_choice), by = cyl] %>% as_tibble() } # 测试调用 my_wrapper("my_lovely_colname")
调用后返回的汇总列名即为传入的my_lovely_colname。
方案2:手动构造返回列表(适合多动态列场景)
如果需要同时生成多个自定义名称的列,直接在j参数中构造命名列表:
my_wrapper_multi <- function(max_col = "max_mpg", min_col = "min_mpg") { mtcars %>% as.data.table() %>% .[, { res <- list() res[[max_col]] <- max(mpg) res[[min_col]] <- min(mpg) res }, by = cyl] %>% as_tibble() }
方案3:env 参数(官方推荐编程规范,data.table 1.14.3+支持)
data.table后续版本新增了env参数专门用于编程场景,和dplyr的编程接口思路一致,避免非标准求值的潜在问题:
my_wrapper <- function(new_colname_of_choice) { mtcars %>% as.data.table() %>% .[, .(tmp_col = max(mpg)), by = cyl, env = list(tmp_col = new_colname_of_choice)] %>% as_tibble() }
该写法稳定性最高,是官方推荐的封装函数时的标准实现方案。
内容的提问来源于stack exchange,提问作者Emman
相关产品推荐
相关产品推荐

