Могу ли я создать несколько столбцов из одной группы путем изменения?

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

Names = append(rep('Mark',10),rep('Joe',10))
Spend = rnorm(length(Names),50,0.5)

df <- data.frame(
  Names,
  Spend
)


get.mm <- function(data){


  return(list(median(data),mean(data)))
}

Здесь get.mm возвращает список из двух чисел. Я хотел бы применить get.mm к df %>% group_by(Names) и получить в результате два столбца, по одному для каждого вывода функции.

Желаемый результат должен быть

  Names   median    mean
  <fctr>    <dbl>   <dbl>
1    Joe 49.89284 49.9504
2   Mark 50.17244 50.0735

Я упростил функцию здесь для демонстрации, я знаю, что мог бы просто сделать что-то вроде

df %>% group_by(Names) %>% summarise(median = median(Spend), mean = mean(Spend))

person Demetri Pananos    schedule 28.07.2017    source источник
comment
см. summarise_at() и cran.r-project.org/web/packages /dplyr/виньетки/   -  person Alex P    schedule 28.07.2017
comment
Эта запись в блоге очень актуальна: r-bloggers.com/ программирование-с-dplyr-при-использовании-dplyr   -  person Alex P    schedule 28.07.2017


Ответы (1)


Если вы перепишите get.mm так, чтобы он возвращал фрейм данных, то вы можете использовать group_by %>% do:

get.mm <- function(data){
    data.frame(median = median(data), mean = mean(data))
}

df %>% group_by(Names) %>% do(get.mm(.$Spend))  
# here . stands for a sub data frame with a unique Name, .$Spend passes the corresponding
# column to the function

Воспроизводимый пример:

set.seed(1)
Names = append(rep('Mark',10),rep('Joe',10))
Spend = rnorm(length(Names),50,0.5)
df <- data.frame(Names, Spend)

df %>% group_by(Names) %>% do(get.mm(.$Spend))

# A tibble: 2 x 3
# Groups:   Names [2]
#   Names   median     mean
#  <fctr>    <dbl>    <dbl>
#1    Joe 50.24594 50.12442
#2   Mark 50.12829 50.06610

df %>% group_by(Names) %>% summarise(median = median(Spend), mean = mean(Spend))

# A tibble: 2 x 3
#   Names   median     mean
#  <fctr>    <dbl>    <dbl>
#1    Joe 50.24594 50.12442
#2   Mark 50.12829 50.06610
person Psidom    schedule 28.07.2017
comment
Я не очень часто dplyr-er, но что-то вроде df %>% group_by(Names) %>% summarise_all(funs(mean,median)) приемлемо? - person thelatemail; 28.07.2017
comment
@thelatemail Это определенно работает и отличный вариант здесь. group_by %>% do подходит, когда случаи более сложные, как указано в OP. - person Psidom; 28.07.2017