按组别计算多个分位数的ddply函数

16

我该如何进行这个计算:

library(ddply)
quantile(baseball$ab)
  0%  25%  50%  75% 100% 
  0   25  131  435  705 

按组别,比如按"team"?我想要一个行名称为"team"、列名称为"0% 25% 50% 75% 100%"的数据框,即每个组别进行一次quantile调用。

正在处理中...

ddply(baseball,"team",quantile(ab))

不是正确的解决方案。我的问题是每个分组操作的输出在这里都是长度为5的向量。

换句话说,有什么简洁的解决方案(不考虑标题):

m=data.frame()
for (i in unique(baseball$team)){m=rbind(m,quantile(baseball[baseball$team==i, ]$ab))}
head(m,3)
  X120 X120.1 X120.2 X120.3 X120.4
1  120  120.0  120.0 120.00    120
2  162  162.0  162.0 162.00    162
3   89   89.0   89.0  89.00     89
4个回答

25

使用基础R,您可以使用tapplydo.call

library(plyr)
do.call("rbind", tapply(baseball$ab, baseball$team, quantile))

do.call("rbind", tapply(baseball$ab, baseball$team, quantile, c(0.05, 0.1, 0.2)))

或者,使用ddply

ddply(baseball, .(team), function(x) quantile(x$ab))

那是正确的答案!(我只是弄错了匿名函数的定义)。谢谢! - Florian Oswald
是的,我知道有更简单的方法,但是想不出来。非常好的解决方案。 - Mikko

9

使用dplyr的稍有不同的方法:

library(tidyverse)

baseball %>% 
  group_by(team) %>% 
  nest() %>% 
  mutate(
    ret = map(data, ~quantile(.$ab, probs = c(0.25, 0.75))),
    ret = invoke_map(tibble, ret)
  ) %>%
  unnest(ret)

probs参数中,您可以指定所需的分位数。

似乎需要调用invoke_map,因为quantile不会返回数据框; 请参见此答案

您还可以将所有内容放入函数中:

get_quantiles <- function(.data, .var, .probs = c(0.25, 0.75), .group_vars = vars()) {
  .var = deparse(substitute(.var))
  return(
    .data %>% 
    group_by_at(.group_vars) %>% 
    nest() %>% 
    mutate(
      ret = map(data, ~quantile(.[[.var]], probs = .probs)),
      ret = invoke_map(tibble, ret)
    ) %>%
    unnest(ret, .drop = TRUE)
  )
}

mtcars %>% get_quantiles(wt, .group_vars = vars(cyl))

一个新的方法是使用dplyr中的group_modify()。然后你可以调用:

baseball %>%
  group_by(team) %>% 
  group_modify(~{
    quantile(.x$ab, probs = c(0.25, 0.75)) %>% 
    tibble::enframe()
  }) %>%
  spread(name, value)

3
你应该分别定义每个分位数的计算方法并使用summarise。同时使用.(team)
library(plyr)
data(baseball)
ddply(baseball,.(team),summarise, X0 = quantile(ab, probs = 0), X25 = quantile(ab, probs = 0.25), X50 = quantile(ab, probs = 0.50), X75 = quantile(ab, probs = 0.75), X100 = quantile(ab, probs = 1))

这个答案也很棒。我想要自定义分位数,而不是标准四分位数,所以这正是我需要的。 - rwking

2
你可以使用非标准分位数在 dplyr 中完成此操作:
library(plyr)
data(baseball)
library(dplyr)
prob=c(0.2, 0.8)
summarise(group_by(baseball,team), 
    p1 = quantile(ab, probs = prob[1]), 
    p2 = quantile(ab, probs = prob[2]))

注意,这里使用的是 dplyr::summarise,而不是 plyr::summarise

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接