R 中 plyr::ldply(tapply) 的 dplyr 等价物是什么?
What is the dplyr equivalent of plyr::ldply(tapply) in R?
最终,我正在尝试实现类似于以下内容,但利用 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
。此外,请注意,我丢失了列 headers 的 %
格式,因为我将第一列中的 .id
替换为 cyl
。
问题:
- 是否有更好的基于
dplyr
的方法来完成此任务
tapply %>% ldply
链?
- 有没有办法兼顾两者的优点
没有跳过太多箍的世界?也就是说,得到
%
第一列的格式和正确的 cyl
列名称?
使用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
@akrun 的版本很好,但我会在 do
语句中使用 data_frame_
。
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_
的这个特性实际上可能是一个错误。
最终,我正在尝试实现类似于以下内容,但利用 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
。此外,请注意,我丢失了列 headers 的 %
格式,因为我将第一列中的 .id
替换为 cyl
。
问题:
- 是否有更好的基于
dplyr
的方法来完成此任务tapply %>% ldply
链? - 有没有办法兼顾两者的优点
没有跳过太多箍的世界?也就是说,得到
%
第一列的格式和正确的cyl
列名称?
使用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
@akrun 的版本很好,但我会在 do
语句中使用 data_frame_
。
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_
的这个特性实际上可能是一个错误。