评估数据表中的文本

时间:2015-05-07 03:58:06

标签: r eval data.table

我正在尝试通过单个变量在非常大的数据表中聚合很多变量。我遇到的问题是eval(parse(text=...)),我认为这是因为我正在评估几个表达式而不仅仅是一个表达式。这是一个简单的例子:

library(data.table)
data(mtcars)
mtcars<-as.data.table(mtcars)

mtcars[,j=list(
  eval(parse(text='mean_mpg=mean(mpg),
             sum_mpg=sum(mpg)'))

),by=gear]

Error in parse(text = "mean_mpg=mean(mpg),\n             sum_mpg=sum(mpg)") : 
  <text>:1:19: unexpected ','
1: mean_mpg=mean(mpg),

目标:

mtcars[,j=list(
  mean_mpg=mean(mpg),
  sum_mpg=sum(mpg)

),by=gear]
   gear mean_mpg sum_mpg
1:    4 24.53333   294.4
2:    3 16.10667   241.6
3:    5 21.38000   106.9

我将在paste中使用它,但我认为用这种方式写出来更容易。

非常感谢!

1 个答案:

答案 0 :(得分:5)

一次制作大量这些变量的一种方法是利用.SD便利变量。

将函数应用于的关键变量:

key.vars <- c("mpg","disp","hp")

提取meansum个变量:

mtcars[, (c(paste0("mean_",key.vars),paste0("sum_",key.vars))) := 
          c(lapply(.SD,mean),lapply(.SD,sum)), 
          by=gear, .SDcols=key.vars]

结果:

head(mtcars)
    mpg cyl disp  hp drat    wt  qsec vs am gear carb mean_mpg mean_disp  mean_hp sum_mpg sum_disp sum_hp
1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4 24.53333  123.0167  89.5000   294.4   1476.2   1074
2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4 24.53333  123.0167  89.5000   294.4   1476.2   1074
3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1 24.53333  123.0167  89.5000   294.4   1476.2   1074
4: 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1 16.10667  326.3000 176.1333   241.6   4894.5   2642
5: 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2 16.10667  326.3000 176.1333   241.6   4894.5   2642
6: 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1 16.10667  326.3000 176.1333   241.6   4894.5   2642

如果您不想附加到当前表,可以使用此类似代码:

output <- mtcars[, c(lapply(.SD,mean),lapply(.SD,sum)), by=gear, .SDcols=key.vars]
setnames(output,c("gear",c(paste0("mean_",key.vars),paste0("sum_",key.vars))))
output

结果:

   gear mean_mpg mean_disp  mean_hp sum_mpg sum_disp sum_hp
1:    4 24.53333  123.0167  89.5000   294.4   1476.2   1074
2:    3 16.10667  326.3000 176.1333   241.6   4894.5   2642
3:    5 21.38000  202.4800 195.6000   106.9   1012.4    978

我不确定你想要做什么,但我认为使用长而不是广泛的聚合数据是最容易的。

sum.list <- lapply(key.vars, function(x) mtcars[, .(Var=x,Mean=mean(get(x)),Sum=sum(get(x))), by=gear])
sum.table <- rbindlist(sum.list,fill=T)
sum.table

结果:

   gear  Var      Mean    Sum
1:    4  mpg  24.53333  294.4
2:    3  mpg  16.10667  241.6
3:    5  mpg  21.38000  106.9
4:    4 disp 123.01667 1476.2
5:    3 disp 326.30000 4894.5
6:    5 disp 202.48000 1012.4
7:    4   hp  89.50000 1074.0
8:    3   hp 176.13333 2642.0
9:    5   hp 195.60000  978.0

似乎更容易使用。