R中plyr :: ldply(tapply)的dplyr等价物是什么?

时间:2015-06-02 13:27:38

标签: r plyr dplyr tidyr

最终,我正在努力实现类似以下内容,但利用dplyr代替plyr

library(dplyr)  
probs = seq(0, 1, 0.1)

plyr::ldply(tapply(mtcars$mpg, 
                   mtcars$cyl, 
                   function(x) { quantile(x, probs = probs) }))

#   .id   0%   10%   20%   30%   40%  50%   60%   70%   80%   90% 100%
# 1   4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9
# 2   6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4
# 3   8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2

我能想出的最佳dplyr等价物是这样的:

library(tidyr)
probs = seq(0, 1, 0.1)

mtcars %>%
  group_by(cyl) %>%
  do(data.frame(prob = probs, stat = quantile(.$mpg, probs = probs))) %>%
  spread(prob, stat)

#   cyl    0   0.1   0.2   0.3   0.4  0.5   0.6   0.7   0.8   0.9    1
# 1   4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9
# 2   6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4
# 3   8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2

请注意,我还需要使用tidyr::spread。另外,请注意我已失去列标题的%格式,以便在第一列中将.id替换为cyl

问题:

  1. 是否有更好的基于dplyr的方法来实现这一目标 tapply %>% ldply链?
  2. 有没有办法充分利用两者 世界没有跳过太多的篮球?也就是说,获取% 格式化以及第一列的正确cyl列名称?

2 个答案:

答案 0 :(得分:7)

使用dplyr

library(dplyr)
mtcars %>% 
   group_by(cyl) %>% 
   do(data.frame(as.list(quantile(.$mpg,probs=probs)), check.names=FALSE))
#  cyl   0%   10%   20%   30%   40%  50%   60%   70%   80%   90% 100%
#1   4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9
#2   6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4
#3   8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2

使用data.table

的选项
library(data.table)
as.data.table(mtcars)[, as.list(quantile(mpg, probs=probs)) , cyl]
#   cyl   0%   10%   20%   30%   40%  50%   60%   70%   80%   90% 100%
#1:   6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4
#2:   4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9
#3:   8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2

答案 1 :(得分:5)

@ akrun的版本很好,但我会在data_frame_语句中使用do

mtcars %>% 
  group_by(cyl) %>% 
  do(data_frame_(quantile(.$mpg, probs = probs)))
## Source: local data frame [3 x 12]
## Groups: cyl
## 
##   cyl   0%   10%   20%   30%   40%  50%   60%   70%   80%   90% 100%
## 1   4 21.4 21.50 22.80 22.80 24.40 26.0 27.30 30.40 30.40 32.40 33.9
## 2   6 17.8 17.98 18.32 18.98 19.40 19.7 20.48 21.00 21.00 21.16 21.4
## 3   8 10.4 11.27 13.90 14.66 15.04 15.2 15.44 15.86 16.76 18.28 19.2

在进一步调查其原因后,看起来data_frame_dplyr中使用的常用SE逻辑不同。 data_frame_只接受一个参数columns并且确实需要一个lazy_dots参数。

如果它得到一个向量,它就可以工作,因为对各个参数的惰性求值是有效的。因此,在这样的向量上使用data_frame_的这个功能实际上可能是一个错误。