Bisakah saya membuat beberapa kolom dari satu grup dengan bermutasi?

Saya ingin mengelompokkan kerangka data saya pada kolom tertentu dan kemudian menerapkan fungsi ke data yang dikelompokkan yang mengembalikan beberapa kolom. Sebagai contoh, perhatikan hal berikut

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)))
}

Di sini, get.mm mengembalikan daftar dua angka. Saya ingin menerapkan get.mm ke df %>% group_by(Names) dan mendapatkan hasilnya memiliki dua kolom, satu untuk setiap output fungsi.

Hasil yang diinginkan seharusnya

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

Saya telah menyederhanakan fungsinya di sini sebagai sarana demonstrasi, saya tahu saya bisa melakukan sesuatu seperti itu

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

person Demetri Pananos    schedule 28.07.2017    source sumber
comment
lihat summarise_at() dan cran.r-project.org/web/packages /dplyr/sketsa/   -  person Alex P    schedule 28.07.2017
comment
Entri blog ini sangat relevan: r-bloggers.com/ pemrograman-dengan-dplyr-dengan-menggunakan-dplyr   -  person Alex P    schedule 28.07.2017


Jawaban (1)


Jika Anda menulis ulang get.mm sehingga mengembalikan bingkai data, Anda dapat menggunakan 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

Contoh yang dapat direproduksi:

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
Saya bukan seorang dplyr-er terlalu sering, tetapi apakah hal seperti df %>% group_by(Names) %>% summarise_all(funs(mean,median)) dapat diterima? - person thelatemail; 28.07.2017
comment
@thelatemail Itu pasti berhasil dan merupakan pilihan bagus di sini. group_by %>% do cocok jika kasusnya lebih rumit seperti yang ditunjukkan oleh OP. - person Psidom; 28.07.2017