`dplyr::summarise` tidak menerima fungsi eksternal

Saya memiliki kumpulan data berikut:

dataset=structure(list(var1 = c(28.5627505742013, 22.8311421908438, 95.2216156944633, 
43.9405107684433, 97.11211245507, 48.4108281508088, 77.1804554760456, 
27.1229329891503, 69.5863061584532, 87.2112890332937), var2 = c(32.9009465128183, 
54.1136392951012, 69.3181485682726, 70.2100433968008, 44.0986660309136, 
62.8759404085577, 79.4413498230278, 97.4315509572625, 62.2505457513034, 
76.0133410431445), var3 = c(89.6971945464611, 67.174579706043, 
37.0924087055027, 87.7977314218879, 29.3221596442163, 37.5143952667713, 
62.6237869635224, 71.3644423149526, 95.3462834469974, 27.4587387405336
), var4 = c(41.5336912125349, 98.2095112837851, 80.7970978319645, 
91.1278881691396, 66.4086666144431, 69.2618868127465, 67.7560870349407, 
71.4932355284691, 21.345994155854, 31.1811877787113), var5 = c(33.9312525652349, 
88.1815139763057, 98.4453701227903, 25.0217059068382, 41.1195872165263, 
37.0983888953924, 66.0217586159706, 23.8814191706479, 40.9594196081161, 
79.7632974945009), var6 = c(39.813664201647, 80.6405956856906, 
30.0273275375366, 34.6203793399036, 96.5195455029607, 44.5830867439508, 
78.7370151281357, 42.010761089623, 23.0079878121614, 58.0372223630548
), kmeans = structure(c(2L, 1L, 3L, 1L, 3L, 1L, 1L, 1L, 2L, 3L
), .Label = c("1", "2", "3"), class = "factor")), .Names = c("var1", 
"var2", "var3", "var4", "var5", "var6", "kmeans"), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"))

Dan fungsi berikut:

myfun<-function(x){
  c(sum(x),mean(x),sd(x))
}

Dengan dplyr::summarise saja, hasilnya oke:

library(tidyverse)

my1<-dataset%>%
  summarise_if(.,is.numeric,.funs=funs(sum,mean,sd))

Namun, dengan myfun tidak berfungsi:

my2<-dataset%>%
  summarise_if(.,is.numeric,.funs=funs(myfun))

Kesalahan dalam summarise_impl(.data, titik): Kolom var1 harus panjangnya 1 (nilai ringkasan), bukan 3

Apa masalahnya?


person neves    schedule 12.01.2019    source sumber
comment
Bisakah Anda memberikan contoh yang menunjukkan summarise berfungsi? Maafkan ketidaktahuan saya, bagaimana cara mengembalikan tiga nilai ke dalam satu kolom? Apa kesalahan sebenarnya yang Anda dapatkan?   -  person NelsonGon    schedule 12.01.2019
comment
Masalahnya adalah mengatur beberapa nilai ke satu kolom. Saya tidak tahu berapa lama waktu yang dibutuhkan, tetapi Anda dapat menjalankan fungsi-fungsi ini secara terpisah.   -  person NelsonGon    schedule 12.01.2019
comment
Periksa saja perbedaan antara funs(sum, mean, sd) dan funs(c(sum, mean, sd))   -  person Rich Scriven    schedule 12.01.2019


Jawaban (3)


Anda dapat mencoba pendekatan ini, Pendekatan Anda tidak akan memberikan hasil yang benar karena pendekatan tersebut tidak dapat menggabungkan dua nilai yang dikembalikan oleh fungsi khusus Anda dalam satu sel, untuk menghindari masalah, saya menggunakan enframe dengan list dalam fungsi khusus:

library(tidyverse)

myfun<-function(x){
    return(list(enframe(c('sum' = sum(x),'mean' = mean(x),'sd' = sd(x)))))
}

Misalnya dengan mtcars data:

my2<-mtcars%>%
summarise_at(c('mpg','drat'), function(x) myfun(x)) %>% 
unnest() %>% 
select(-name1) %>% 
set_names(nm = c('name', 'mpg', 'drat'))

itu akan menghasilkan:

  name        mpg        drat
1  sum 642.900000 115.0900000
2 mean  20.090625   3.5965625
3   sd   6.026948   0.5346787

Selain itu, ada satu cara alternatif untuk mencoba menyelesaikannya menggunakan purrr.

Misalnya:

f <- function(x,...){
    list('mean' = mean(x, ...),'sum' = sum(x, ...))
}

mtcars %>% 
select(mpg, drat) %>% 
map_dfr(~ f(.x, na.rm=T), .id ="Name") %>% 
data.frame()
person PKumar    schedule 12.01.2019

Saat Anda menerapkan fungsi ini

dataset%>% summarise_if(is.numeric,.funs=funs(sum,mean,sd))

Anda menerapkan tiga fungsi berbeda (sum, mean dan sd) yang diterapkan ke semua kolom satu per satu. Jadi setiap kolom numerik, fungsi ini akan diterapkan padanya. Di sini kita mendapatkan tiga fungsi berbeda yang mengembalikan tiga nilai.

Mengenai fungsi Anda, menurut saya yang Anda coba lakukan adalah

myfun<-function(x){
  c(sum(x),mean(x),sd(x))
}

Sekarang, ketika fungsi ini diterapkan ke satu kolom, ia mengembalikan Anda tiga nilai, jadi di sini satu fungsi mengembalikan Anda tiga nilai.

myfun(dataset$var1)
#[1] 597.17994  59.71799  29.03549

Seperti yang disebutkan @NelsonGon di komentar, Anda mencoba menyimpan tiga nilai dalam satu kolom. Anda dapat mengembalikannya sebagai daftar seperti yang ditunjukkan @Pkumar atau beberapa variasi do juga akan membantu Anda mencapainya. Jika Anda memecah fungsi dan membuat tiga fungsi secara terpisah, cara kerjanya akan sama seperti yang Anda tunjukkan sebelumnya.

myfun1 <- function(x) sum(x)
myfun2  <- function(x) mean(x)
myfun3 <- function(x) sd(x)

dataset %>% summarise_if(is.numeric,.funs=funs(myfun1,myfun2,myfun3))
person Ronak Shah    schedule 12.01.2019

ini bukan cara yang paling elegan, tetapi jika fungsi eksternal Anda hanyalah daftar fungsi lainnya, mungkin Anda bisa menggunakan daftar untuk fungsi Anda saja:

myfun_ls <- list(sum,mean,sd)
my2<-dataset%>%
  summarise_if(.,is.numeric,.funs=myfun_ls)
person JMueller    schedule 12.01.2019