【问题标题】:Changing default column names in R data.table aggregations更改 R data.table 聚合中的默认列名
【发布时间】:2018-07-09 04:38:26
【问题描述】:

在交互模式下,探索 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

【问题讨论】:

  • 以下答案将阻止GForce 优化您的查询。您的 IDE 没有自动完成功能吗?如果你只是玩玩,我认为使用V1V5 之类的名称不会受到太大影响。如果这不是短暂的,编写显式代码将帮助其他人(包括未来的你)更好地理解你的代码。选择从聚合变量的名称中删除 summean 让我觉得很麻烦/乞求混淆/错误。
  • 欢迎就这些问题发表意见。我认为自动命名排除聚合的方法 没有任何意义(即我认为可以接受的任何解决方案都类似于v_a_long_name_sumy_a_long_name_mean
  • 是的,自动化包含方法会更好(只是输入更多)。是的,大多数时候代码会被长期保存,所以自动命名会很好

标签: r data.table


【解决方案1】:

我们可以使用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])[]

【讨论】:

  • @QuantitativeMelancholy 抱歉,感谢您的意见。您不需要完整的列名,但可以使用setnames 进行索引来分配。更新
  • 我喜欢这种方法,尽管当它是一个大数据表时,它仍然需要更多的打字和思考来选择正确的列等。如果有一些默认选项可以在应用某个函数后返回列的名称,那就太好了。
  • @QuantitativeMelancholy 您可以将get 与名称一起使用
【解决方案2】:

有点迂回的解决方案,但您可以将函数列表和列列表传递给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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 2015-07-01
    • 1970-01-01
    • 2015-04-29
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    相关资源
    最近更新 更多