【问题标题】:Get column names when summarising a data table using multiple functions in R使用 R 中的多个函数汇总数据表时获取列名
【发布时间】:2017-01-20 15:58:28
【问题描述】:

我有一个包含多列的数据表。一个简短的可重复示例如下:

 library(data.table)
 DT = setDT(structure(list(ZONE = c("WEST", "WEST", "WEST", "EAST", "EAST", 
"EAST", "EAST"), PULSES = c(347, 70, 110, 720, 280, 190, 35), 
    FRUITS = c(172, 130, 0, 578, 350, 220, 50), CEREALS = c(740, 
    639, 149, 1381, 2415, 1765, 525), newmlt = c(8248, 838.5, 
    287.75, 46, 60.375, 38.81, 38.81)), .Names = c("ZONE", "PULSES", 
"FRUITS", "CEREALS", "newmlt"), row.names = c(NA, -7L), class = c("data.table", 
"data.frame")))

我试图通过在同一列上应用不同的函数来汇总数据框的多个列(动态变化),从而产生多个汇总。例如:以下是部分函数:

非零百分比的函数

usrs <- function(x) round(length(x[x != 0])/length(x)*100,0)

用一个平均数来结束它

my.summary = function(x) list(MEAN = mean(x), 'USERS_%' = usrs(x))

选择要汇总的列

cols <- c('PULSES', 'CEREALS')

使用数据表

cerr <- DT[, unlist(lapply(.SD, my.summary)), .SDcols = cols, by = ZONE]
cerr

group by 选项也会动态变化。 但是,我没有使用上面的代码获取列名。如何获取列名以及区域和 V1。

我也尝试了setkey(DT, ZONE) 并使用了by = .EACHI - 但我的usrs 函数获得了NA。

我想要的输出如下:

   ZONE     COL         V1
1: WEST MEAN.PULSES   175.6667
2: WEST usrs.PULSES   100.0000
3: WEST MEAN.CEREALS  509.3333
4: WEST usrs.CEREALS  100.0000
5: EAST MEAN.PULSES   306.2500
6: EAST usrs.PULSES   100.0000
7: EAST MEAN.CEREALS  1521.5000
8: EAST usrs.CEREALS  100.0000

如何将列名也作为输出中的列之一。

【问题讨论】:

  • df[ , c(list(cols), lapply(.SD, my.summary))]
  • 我建议 melt(DT[, c("ZONE", cols), with=FALSE], id="ZONE")[, .(m = mean(value), nz = round(mean(value!=0)*100,0)), by=.(ZONE,variable)] (将统计数据保存在不同的列中......如果你真的想要它们堆叠,可以再次 melt)。
  • @Frank 非常感谢......非常适合我的用例......我可以接受这个作为答案。

标签: r data.table


【解决方案1】:

我建议

cols <- c('PULSES', 'CEREALS')
melt(DT[, c("ZONE", cols), with=FALSE], id="ZONE")[, 
  .(m = mean(value), nz = round(mean(value!=0)*100, 0))
, by=.(ZONE,variable)]

#    ZONE variable         m  nz
# 1: WEST   PULSES  175.6667 100
# 2: EAST   PULSES  306.2500 100
# 3: WEST  CEREALS  509.3333 100
# 4: EAST  CEREALS 1521.5000 100

如果您希望数据堆叠而不是单独的列,请再次melt


或者,您可以为所有列计算它并在之后进行过滤:

cols <- c('PULSES', 'CEREALS')
melt(DT, id="ZONE")[, 
  .(m = mean(value), nz = round(mean(value!=0)*100,0))
, by=.(ZONE,variable)][ variable %in% cols ]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 2021-02-05
    • 2021-10-13
    • 2017-06-20
    • 2022-01-14
    • 1970-01-01
    • 2021-04-23
    相关资源
    最近更新 更多