更改R data.table聚合中的默认列名称

时间:2018-07-09 04:38:27

标签: r data.table

在交互模式下,探索data.table中的聚合时,我可能会进行数十个或数百个实验。在编写了生成聚合所需的最少代码量之后,聚合之后的默认列名(V1V2等)显然不是很有帮助。通常,我更喜欢使用一列的简单聚合的默认列名,例如均值或总和,只是基础变量的名称。

所有多余的列名称键入都会很累,我想避免这种情况。

data.table中有什么简单的方法可以做到这一点?

例如一个简化的示例来演示不清楚的地方:

DT = data.table(x =rep(c("b","a","c"),each=3), y_a_long_name=c(1,3,6), v_a_long_name=1:9)

DT[, .(sum(v_a_long_name), mean(y_a_long_name)), by = x]
#    x V1       V2
# 1: b  6 3.333333
# 2: a 15 3.333333
# 3: c 24 3.333333

当您开始使用不同的聚合类型函数处理多个列时,上面的标签V1V2并没有帮助。

重复名称的所有其他额外输入都很乏味,但是我希望看到这样的内容:

DT[, .(v_a_long_name = sum(v_a_long_name), y_a_long_name = mean(y_a_long_name)), by = x]
#    x v_a_long_name y_a_long_name
# 1: b             6      3.333333
# 2: a            15      3.333333
# 3: c            24      3.333333

,同时输入尽可能少的字符。例如

DT[, .(sum(v_a_long_name), mean(y_a_long_name)), by = x]

默认打印此:

#    x v_a_long_name y_a_long_name
# 1: b             6      3.333333
# 2: a            15      3.333333
# 3: c            24      3.333333

2 个答案:

答案 0 :(得分:2)

我们可以使用setNames包裹列的list

DT[, setNames(.(sum(v_a_long_name), mean(y_a_long_name)), names(DT)[2:3]), by = x]
#   x y_a_long_name v_a_long_name
#1: b             6      3.333333
#2: a            15      3.333333
#3: c            24      3.333333

或在获得输出后使用setnames

setnames(DT[, .(sum(v_a_long_name), mean(y_a_long_name)),
                         by = x], 2:3, names(DT)[2:3])[]

或者通过从.SD提取列来使其更紧凑

setnames(DT[, .(sum(.SD[[2]]), mean(.SD[[1]])), by = x], 2:3, names(DT)[2:3])[]

答案 1 :(得分:1)

有些回旋解决方案,但是您可以将函数列表和列列表传递给Map + do.call。结果列的名称将从Map的第一个参数获取,这意味着您只需在.SDcols中以长格式指定一次名称:

DT[, 
  Map(do.call, args=lapply(.SD,list), what=c(sum,mean)),
  by=x, .SDcols=c("v_a_long_name","y_a_long_name")
]

#   x v_a_long_name y_a_long_name
#1: b             6      3.333333
#2: a            15      3.333333
#3: c            24      3.333333

如果需要自动命名,则可以提前定义变量:

nms  <- c("v_a_long_name","y_a_long_name")
funs <- c("sum","mean")

DT[, 
  setNames(Map(do.call, args=lapply(.SD,list), what=funs), paste(nms,funs,sep="_")),
  by=x, .SDcols=nms
]

#   x v_a_long_name_sum y_a_long_name_mean
#1: b                 6           3.333333
#2: a                15           3.333333
#3: c                24           3.333333