我有一个包含多列的数据表。一个简短的可再现的例子如下:
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')
使用data.table
cerr <- DT[, unlist(lapply(.SD, my.summary)), .SDcols = cols, by = ZONE]
cerr
group by选项也会动态更改。 但是,我没有使用上面的代码获取列名。如何获取列名以及区域和V1。
我也尝试了setkey(DT, ZONE)
并使用了by = .EACHI
- 但是为我的用户功能获得了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
如何将列名称作为输出中的一列获取。
答案 0 :(得分:2)
我建议
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计算并在之后过滤:
cols <- c('PULSES', 'CEREALS')
melt(DT, id="ZONE")[,
.(m = mean(value), nz = round(mean(value!=0)*100,0))
, by=.(ZONE,variable)][ variable %in% cols ]