使用R

时间:2017-01-20 15:58:29

标签: r data.table

我有一个包含多列的数据表。一个简短的可再现的例子如下:

 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

如何将列名称作为输出中的一列获取。

1 个答案:

答案 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 ]