2016-09-12 6 views
4

Пусть даны dataframe с 2-мя колоннами, id и value, я хочу, чтобы превратить его в dataframe с несколькими столбцами, содержащими id и квантилей из колонки value: q0, q25, q50, q75 , q100.отдельный столбец списка в столбцы в R

Я не знаю, как разделить столбец, содержащий список, на большее количество столбцов, содержащих его значения. Конечно, все списки имеют одинаковую длину.

Вот пример:

library(dplyr) 
library(tidyr) 

set.seed(0) 
df <- data.frame(id = rep(c("Alice", "Bob"), each = 10), 
       value = round(rnorm(20) * 10)) 
> df 
 
     id value 
1 Alice 13 
2 Alice -3 
3 Alice 13 
4 Alice 13 
5 Alice  4 
6 Alice -15 
7 Alice -9 
8 Alice -3 
9 Alice  0 
10 Alice 24 
11 Bob  8 
12 Bob -8 
13 Bob -11 
14 Bob -3 
15 Bob -3 
16 Bob -4 
17 Bob  3 
18 Bob -9 
19 Bob  4 
20 Bob -12 
df_quantiles <- df %>% 
    group_by(id) %>% 
    summarise(quantiles = list(quantile(value))) %>% 
    ungroup() 
> df_quantiles 
 
    # A tibble: 2 x 2 
      id quantiles 
      
    1 Alice 
    2 Bob 
> df_quantiles$quantiles 
 
[[1]] 
    0% 25% 50% 75% 100% 
-15 -3 2 13 24 

[[2]] 
    0% 25% 50% 75% 100% 
-12.00 -8.75 -3.50 1.50 8.00 

Следующая команда не делает работу. Не могли бы вы помочь мне с хорошим звонком separate? Есть ли другой способ получить результат?

 
> df_quantiles %>% 
+ separate(quantiles, paste0("q", seq(0,5))) 
# A tibble: 2 x 7 
     id q0 q1 q2 q3 q4 q5 
*  
1 Alice  c 15  3  2 13 24 
2 Bob  c 12  8 75  3  5 
Warning message: 
Too many values at 2 locations: 1, 2 

Что я ожидаю это dataframe:

id  q0% q25% q50% q75% q100% 
1 Alice -15  -3  2  13  24 
2 Bob -12.00 -8.75 -3.50 1.50 8.00 
+2

Просто попробуйте 'aggregate (df $ value, df [" id "], quantile)'. – nicola

ответ

2

Если вам нужно dplyr решение, вы можете использовать его как:

library(dplyr) 
df %>% 
    group_by(id) %>% 
    do(data.frame(t(quantile(.$value)))) 

#  id X0. X25. X50. X75. X100. 
# <fctr> <dbl> <dbl> <dbl> <dbl> <dbl> 
#1 Alice -15 -3.00 2.0 13.0 24 
#2 Bob -12 -8.75 -3.5 1.5  8 
2

Мы можем использовать data.table

library(data.table) 
setDT(df)[, as.list(quantile(value)) , by = id] 
#  id 0% 25% 50% 75% 100% 
#1: Alice -15 -3.00 2.0 13.0 24 
#2: Bob -12 -8.75 -3.5 1.5 8 

Или с помощью dplyr

library(dplyr) 
df %>% 
    group_by(id) %>% 
    do(data.frame(as.list(quantile(.$value)))) 
#  id X0. X25. X50. X75. X100. 
# <fctr> <dbl> <dbl> <dbl> <dbl> <dbl> 
#1 Alice -15 -3.00 2.0 13.0 24 
#2 Bob -12 -8.75 -3.5 1.5  8 
+1

't'is значительно быстрее, чем' as.list' Мне нравится решение dplyr :) – Costin

4

Как насчет

cbind.data.frame(id=unique(df$id), do.call(rbind, df_quantiles$quantiles)) 

с выходом

id 0% 25% 50% 75% 100% 
1 Alice -15 -3.00 2.0 13.0 24 
2 Bob -12 -8.75 -3.5 1.5 8 
2

Комбинацию списка, as_tibble из Тиббл , as.list и disest from tidyr выполняет работу

library(tidyverse) 
df_quantiles <- df %>% 
    group_by(id) %>% 
    summarise(quantiles = list(as_tibble(as.list(quantile(value))))) %>% unnest() %>% 
    ungroup() 

 Смежные вопросы

  • Нет связанных вопросов^_^