Saat bekerja dengan plyr
saya sering merasa berguna untuk digunakan adply
untuk fungsi skalar yang harus saya terapkan ke setiap baris.
misalnya
data(iris)
library(plyr)
head(
adply(iris, 1, transform , Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 5.1
2 4.9 3.0 1.4 0.2 setosa 4.9
3 4.7 3.2 1.3 0.2 setosa 4.7
4 4.6 3.1 1.5 0.2 setosa 4.6
5 5.0 3.6 1.4 0.2 setosa 5.0
6 5.4 3.9 1.7 0.4 setosa 5.4
Sekarang saya menggunakan dplyr
lebih banyak, saya bertanya-tanya apakah ada cara yang rapi / alami untuk melakukan ini? Karena ini BUKAN yang saya inginkan:
library(dplyr)
head(
mutate(iris, Max.Len= max(Sepal.Length,Petal.Length))
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Max.Len
1 5.1 3.5 1.4 0.2 setosa 7.9
2 4.9 3.0 1.4 0.2 setosa 7.9
3 4.7 3.2 1.3 0.2 setosa 7.9
4 4.6 3.1 1.5 0.2 setosa 7.9
5 5.0 3.6 1.4 0.2 setosa 7.9
6 5.4 3.9 1.7 0.4 setosa 7.9
mdply
di dplyr, dan hadley menyarankan bahwa mereka mungkin membuat sesuatu berdasarkando
. Saya kira itu juga akan berhasil di sini.rowwise()
yang akan dikelompokkan berdasarkan setiap barisadply
saat Anda tidak menggunakan pengelompokan? karena fungsinya yang terintegrasi erat disebutgroup_by
NOTsplit_by
Jawaban:
Sejak dplyr 0.2 (menurut saya)
rowwise()
diimplementasikan, jadi jawaban untuk masalah ini menjadi:Bukan
rowwise
alternatifLima tahun kemudian (!) Jawaban ini masih banyak trafik. Sejak diberikan,
rowwise
semakin tidak disarankan, meskipun banyak orang tampaknya menganggapnya intuitif. Bantulah diri Anda sendiri dan ikuti alur kerja Jenny Bryan yang berorientasi pada baris di R dengan materi rapi untuk mendapatkan pegangan yang baik tentang topik ini.Cara paling mudah yang saya temukan didasarkan pada salah satu contoh Hadley yang menggunakan
pmap
:Dengan menggunakan pendekatan ini, Anda bisa memberikan sejumlah argumen ke function (
.f
) di dalamnyapmap
.pmap
adalah pendekatan konseptual yang baik karena merefleksikan fakta bahwa ketika Anda melakukan operasi baris bijak Anda sebenarnya bekerja dengan tupel dari daftar vektor (kolom dalam kerangka data).sumber
plyr
dandplyr
paket, Anda hampir pasti menggunakan kesalahanmutate
kecuali Anda secara eksplisit memberikan ruang lingkupdplyr::mutate
.Pendekatan idiomatik akan membuat fungsi vektorisasi yang tepat.
R
menyediakanpmax
yang sesuai di sini, namun juga menyediakanVectorize
sebagai pembungkus untukmapply
memungkinkan Anda membuat versi arbitrer yang di-vectorisasi dari fungsi arbitrer.Perhatikan bahwa mengimplementasikan vektorisasi di C / C ++ akan lebih cepat, tetapi tidak ada
magicPony
paket yang akan menulis fungsinya untuk Anda.sumber
dplyr
cara ... karena akan lebih sederhana tanpa dplyr misalnyawith(df, Coalesce(a,b))
Mungkin, itu adalah jenis jawaban meskipun - jangan gunakandplyr
untuk itu?magicPony
paket. Sayang sekaliAnda perlu mengelompokkan berdasarkan baris:
Inilah yang
1
dilakukan diadply
.sumber
dplyr
ahli. Semoga orang lain datang dengan sesuatu yang lebih baik. Perhatikan saya membersihkannya sedikit dengan1:n()
.group_by(1:n())
perilaku tersebut. Jika tidak ada yang punya ide lain di pagi hari, saya akan mencentang ide Anda;)n
: "Fungsi ini diimplementasikan khusus untuk setiap sumber data dan hanya dapat digunakan dari dalam ringkasan.", Meskipun tampaknya berfungsi.Perbarui 2017-08-03
Setelah menulis ini, Hadley mengubah beberapa hal lagi. Fungsi yang dulu ada di purrr sekarang ada dalam paket campuran baru yang disebut purrrlyr , yang dijelaskan sebagai:
Jadi, Anda perlu menginstal + memuat paket itu agar kode di bawah ini berfungsi.
Posting asli
Hadley sering berubah pikiran tentang apa yang harus kita gunakan, tetapi saya pikir kita harus beralih ke fungsi di purrr untuk mendapatkan fungsi baris. Setidaknya, mereka menawarkan fungsionalitas yang sama dan memiliki antarmuka yang hampir sama seperti
adply
dari plyr .Ada dua fungsi terkait,
by_row
daninvoke_rows
. Pemahaman saya adalah bahwa Anda menggunakanby_row
ketika Anda ingin mengulang baris dan menambahkan hasilnya ke data.frame.invoke_rows
digunakan saat Anda mengulang baris data.frame dan meneruskan setiap kolom sebagai argumen ke suatu fungsi. Kami hanya akan menggunakan yang pertama.Contoh
Ini memungkinkan kita melihat bagian dalamnya (sehingga kita dapat melihat apa yang kita lakukan), yang sama dengan melakukannya
adply
.Secara default,
by_row
menambahkan kolom daftar berdasarkan output:memberikan:
jika sebaliknya kita mengembalikan a
data.frame
, kita mendapatkan daftar dengandata.frame
s:memberikan:
Bagaimana kita menambahkan output dari fungsi ini dikendalikan oleh
.collate
param. Ada tiga opsi: daftar, baris, kolom. Ketika keluaran kita memiliki panjang 1, tidak masalah apakah kita menggunakan baris atau kolom.keduanya menghasilkan:
Jika kita mengeluarkan data.frame dengan 1 baris, itu hanya sedikit yang kita gunakan:
keduanya memberi:
kecuali bahwa yang kedua memiliki kolom yang dipanggil
.row
dan yang pertama tidak.Akhirnya, jika keluaran kita lebih panjang dari panjang 1 baik sebagai a
vector
atau sebagaidata.frame
dengan baris, maka penting apakah kita menggunakan baris atau kolom untuk.collate
:menghasilkan, masing-masing:
Jadi, intinya. Jika Anda menginginkan
adply(.margins = 1, ...)
fungsionalitasnya, Anda dapat menggunakanby_row
.sumber
by_row
tidak digunakan lagi, memanggilnya untuk mengatakan "gunakan kombinasi dari: tidyr :: nest (); dplyr :: mutate (); purrr :: map ()" github.com/hadley/purrrlyr/blob/…Memperluas jawaban BrodieG,
Jika fungsi mengembalikan lebih dari satu baris, maka sebagai gantinya
mutate()
,do()
harus digunakan. Kemudian untuk menggabungkannya kembali, gunakanrbind_all()
daridplyr
paket.Dalam
dplyr
versidplyr_0.1.2
, menggunakan1:n()
dalamgroup_by()
klausul tidak berhasil untuk saya. Semoga Hadleyrowwise()
segera diimplementasikan .Menguji kinerja,
itu memiliki hasil sebagai berikut:
Ini menunjukkan bahwa
purrr
versi baru adalah yang tercepatsumber
Sesuatu seperti ini?
sumber
dplyr
solusi umum untuk fungsi skalar apa pun.wacky.function <- function(col.1, col.2){...}
, laluiris.wacky <- wacky.function(iris$Sepal.Length, iris$Petal.Length)
.dplyr
atauplyr
atau mengatakandata.table
Anda harus mencoba menggunakan idiom mereka sehingga kode Anda tidak menjadi campuran gaya yang sulit untuk dibagikan. Karena itu pertanyaannya.plyr
dokumentasi adalah "plyr adalah seperangkat alat yang memecahkan serangkaian masalah umum: Anda perlu memecah masalah besar menjadi bagian-bagian yang dapat dikelola, mengoperasikan setiap bagian dan kemudian menyatukan semua bagian." Ini sepertinya masalah yang sangat berbeda di mana operasi kolom dasar merupakan alat terbaik. Ini juga mungkin menjelaskan mengapa tidak ada perintahplyr
/ "alami"dplyr
untuk melakukan ini.