按组分组多个分位数

时间:2014-03-14 11:14:17

标签: r plyr

我该怎么做这个计算:

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

由团队说,"团队"?我想要一个带有rownames" team"的data.frame。和列名" 0%25%50%75%100%",即每组一个quantile个电话。

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

不是正确的解决方案。我的问题是每个分组操作的OUTPUT是一个长度为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 个答案:

答案 0 :(得分:16)

使用基座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))

答案 1 :(得分: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))

答案 2 :(得分:3)

使用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不会返回数据帧。参见this answer

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

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 :(得分: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