Saya mencoba untuk mentransfer pemahaman saya tentang plyr ke dplyr, tetapi saya tidak tahu bagaimana cara mengelompokkan berdasarkan beberapa kolom.
# make data with weird column names that can't be hard coded
data = data.frame(
asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE),
a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE),
value = rnorm(100)
)
# get the columns we want to average within
columns = names(data)[-3]
# plyr - works
ddply(data, columns, summarize, value=mean(value))
# dplyr - raises error
data %.%
group_by(columns) %.%
summarise(Value = mean(value))
#> Error in eval(expr, envir, enclos) : index out of bounds
Apa yang saya lewatkan untuk menerjemahkan contoh plyr ke dalam sintaks dplyr-esque?
Sunting 2017 : Dplyr telah diperbarui, sehingga solusi yang lebih sederhana tersedia. Lihat jawaban yang dipilih saat ini.
group_by_
sekarang dijelaskan divignette("nse")
.dots
. Inilah solusi yang diadaptasi dari jawaban @hadley di bawah ini:df %>% group_by_(.dots=list(quote(asihckhdoydk), quote(a30mvxigxkgh))) %>% summarise(n = n())
Jawaban:
Karena pertanyaan ini diposting, dplyr menambahkan versi cakupan
group_by
( dokumentasi di sini ). Ini memungkinkan Anda menggunakan fungsi yang sama dengan yang akan Anda gunakanselect
, seperti:Output dari contoh pertanyaan Anda seperti yang diharapkan (lihat perbandingan plyr di atas dan output di bawah):
Perhatikan bahwa karena
dplyr::summarize
hanya menghapus satu lapisan pengelompokan pada satu waktu, Anda masih memiliki beberapa pengelompokan yang terjadi di tibble yang dihasilkan (yang kadang-kadang dapat menangkap orang dengan mengejutkan kemudian di telepon). Jika Anda ingin benar-benar aman dari perilaku pengelompokan yang tidak terduga, Anda selalu dapat menambahkan%>% ungroup
ke saluran Anda setelah Anda merangkum.sumber
0.7.0
membuat sistem kutipan-tanda kutip tersedia dengan beberapa kolom juga?.dots
argumen untukgroup_by()
seperti:data %>% group_by(.dots = columns) %>% summarize(value = mean(value))
.one_of()
melakukan sesuatu di sini? Saya pikir itu berlebihan dalam konteks ini, karena ungkapan dibungkus dengan panggilan untukvars()
.one_of()
menjadi berlebihan dalam konteks iniselect
sintaks, lihatacross
fungsi baru : dplyr.tidyverse.org/reference/across.html Dalam kasus Anda, itu akan terlihat sepertisummarize(across(all_of(c(''value_A", "value_B")), mean))
Untuk menulis kode secara lengkap, berikut ini adalah pembaruan pada jawaban Hadley dengan sintaks baru:
keluaran:
sumber
asihckhdoydk
...dots <- lapply(names(df)[-3], function(x) as.symbol(x))
untuk membuat.dots
argumen.dots=
adalah langkah penting. jika seseorang memiliki pegangan yang baik tentang mengapa hal itu diperlukan dalamgroup_by
panggilan, dapatkah Anda mengedit jawaban ini? sekarang ini agak sulit dipahami.vignette("nse")
menunjukkan ada tiga cara untuk mengutip yang dapat diterima: formula, kutipan, dan karakter. Kecuali jika Anda khawatir tentang dari lingkungan mana itu akan menarik, Anda mungkin dapat pergi dengangroup_by_(.dots=grp_cols)
Dukungan untuk ini di dplyr saat ini cukup lemah, akhirnya saya pikir sintaksnya akan menjadi seperti:
Tapi itu mungkin tidak akan ada untuk sementara waktu (karena saya perlu memikirkan semua konsekuensinya).
Sementara itu, Anda dapat menggunakan
regroup()
, yang mengambil daftar simbol:Jika Anda memiliki vektor karakter nama kolom, Anda dapat mengonversinya ke struktur yang tepat dengan
lapply()
danas.symbol()
:sumber
as.symbol
menyelesaikannya. Terima kasih! Dalam hal ini membantu dengan pengembangan: skenario ini sangat umum bagi saya. Gabungkan hasil numerik dari setiap kombinasi variabel lainnya.regroup
juga tidak digunakan lagi (setidaknya pada versi 0.4.3).Spesifikasi string kolom dalam
dplyr
sekarang didukung melalui variandplyr
fungsi dengan nama yang diakhiri dengan garis bawah. Misalnya, terkait dengangroup_by
fungsi adagroup_by_
fungsi yang dapat mengambil argumen string. Sketsa ini menjelaskan sintaks dari fungsi-fungsi ini secara rinci.Cuplikan berikut ini dengan bersih menyelesaikan masalah yang semula diajukan oleh @sharoz (perhatikan kebutuhan untuk menuliskan
.dots
argumennya):(Perhatikan bahwa dplyr sekarang menggunakan
%>%
operator, dan%.%
sudah usang).sumber
Sampai dplyr memiliki dukungan penuh untuk argumen string, mungkin inti ini berguna:
https://gist.github.com/skranz/9681509
Ini berisi banyak fungsi wrapper seperti s_group_by, s_mutate, s_filter, dll yang menggunakan argumen string. Anda dapat mencampurnya dengan fungsi dplyr normal. Sebagai contoh
sumber
Ini berfungsi jika Anda memberikan objek (well, Anda tidak, tapi ...) alih-alih sebagai vektor karakter:
di mana
df
adalah Andadata
.?group_by
mengatakan:yang saya artikan bukan versi karakter dari nama-nama itu, tetapi bagaimana Anda akan merujuknya pada
foo$bar
;bar
tidak dikutip di sini. Atau bagaimana Anda akan merujuk ke variabel dalam rumus:foo ~ bar
.@Arun juga menyebutkan bahwa Anda dapat melakukan:
Tapi Anda tidak bisa meneruskan sesuatu yang tidak dievaluasi bukan nama variabel dalam objek data.
Saya kira ini karena metode internal yang digunakan Hadley untuk mencari hal-hal yang Anda sampaikan melalui
...
argumen.sumber
sumber
Satu (kecil) kasus yang hilang dari jawaban di sini, yang ingin saya perjelas, adalah ketika variabel yang dikelompokkan oleh dihasilkan secara dinamis midstream dalam pipa:
Ini pada dasarnya menunjukkan bagaimana menggunakan
grep
bersamagroup_by_(.dots = ...)
untuk mencapai ini.sumber
Contoh umum tentang penggunaan
.dots
argumen sebagai input vektor karakter kedplyr::group_by
fungsi:Atau tanpa nama kode keras untuk variabel pengelompokan (seperti yang diminta oleh OP):
Dengan contoh OP:
Lihat juga sketsa dplyr pada pemrograman yang menjelaskan kata ganti, kuasiquotation, quosures, dan rapi.
sumber