Karena saya menyadari bahwa (sangat bagus) jawaban dari kurangnya posting by
dan aggregate
penjelasan. Ini kontribusi saya.
OLEH
The by
fungsi, seperti yang dinyatakan dalam dokumentasi dapat meskipun, sebagai "pembungkus" untuk tapply
. Kekuatan by
muncul ketika kita ingin menghitung tugas yang tapply
tidak bisa ditangani. Salah satu contohnya adalah kode ini:
ct <- tapply(iris$Sepal.Width , iris$Species , summary )
cb <- by(iris$Sepal.Width , iris$Species , summary )
cb
iris$Species: setosa
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.300 3.200 3.400 3.428 3.675 4.400
--------------------------------------------------------------
iris$Species: versicolor
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.000 2.525 2.800 2.770 3.000 3.400
--------------------------------------------------------------
iris$Species: virginica
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.200 2.800 3.000 2.974 3.175 3.800
ct
$setosa
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.300 3.200 3.400 3.428 3.675 4.400
$versicolor
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.000 2.525 2.800 2.770 3.000 3.400
$virginica
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.200 2.800 3.000 2.974 3.175 3.800
Jika kita mencetak dua objek ini, ct
dan cb
, kita "pada dasarnya" memiliki hasil yang sama dan satu-satunya perbedaan adalah bagaimana mereka ditampilkan dan class
atribut yang berbeda , masing by
- masing untuk cb
dan array
untuk ct
.
Seperti yang telah saya katakan, kekuatan by
muncul ketika kita tidak dapat menggunakan tapply
; kode berikut adalah salah satu contoh:
tapply(iris, iris$Species, summary )
Error in tapply(iris, iris$Species, summary) :
arguments must have same length
R mengatakan bahwa argumen harus memiliki panjang yang sama, katakan "kita ingin menghitung summary
semua variabel di iris
sepanjang faktor Species
": tetapi R tidak bisa melakukan itu karena tidak tahu cara menangani.
Dengan by
fungsi R memberangkatkan metode khusus untuk data frame
kelas dan kemudian membiarkan summary
fungsi tersebut bekerja bahkan jika panjang argumen pertama (dan tipenya juga) berbeda.
bywork <- by(iris, iris$Species, summary )
bywork
iris$Species: setosa
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.300 Min. :1.000 Min. :0.100 setosa :50
1st Qu.:4.800 1st Qu.:3.200 1st Qu.:1.400 1st Qu.:0.200 versicolor: 0
Median :5.000 Median :3.400 Median :1.500 Median :0.200 virginica : 0
Mean :5.006 Mean :3.428 Mean :1.462 Mean :0.246
3rd Qu.:5.200 3rd Qu.:3.675 3rd Qu.:1.575 3rd Qu.:0.300
Max. :5.800 Max. :4.400 Max. :1.900 Max. :0.600
--------------------------------------------------------------
iris$Species: versicolor
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.900 Min. :2.000 Min. :3.00 Min. :1.000 setosa : 0
1st Qu.:5.600 1st Qu.:2.525 1st Qu.:4.00 1st Qu.:1.200 versicolor:50
Median :5.900 Median :2.800 Median :4.35 Median :1.300 virginica : 0
Mean :5.936 Mean :2.770 Mean :4.26 Mean :1.326
3rd Qu.:6.300 3rd Qu.:3.000 3rd Qu.:4.60 3rd Qu.:1.500
Max. :7.000 Max. :3.400 Max. :5.10 Max. :1.800
--------------------------------------------------------------
iris$Species: virginica
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.900 Min. :2.200 Min. :4.500 Min. :1.400 setosa : 0
1st Qu.:6.225 1st Qu.:2.800 1st Qu.:5.100 1st Qu.:1.800 versicolor: 0
Median :6.500 Median :3.000 Median :5.550 Median :2.000 virginica :50
Mean :6.588 Mean :2.974 Mean :5.552 Mean :2.026
3rd Qu.:6.900 3rd Qu.:3.175 3rd Qu.:5.875 3rd Qu.:2.300
Max. :7.900 Max. :3.800 Max. :6.900 Max. :2.500
ini memang berhasil dan hasilnya sangat mengejutkan. Ini adalah objek kelas by
yang sepanjang Species
(katakanlah, untuk masing-masing dari mereka) menghitung summary
setiap variabel.
Perhatikan bahwa jika argumen pertama adalah a data frame
, fungsi yang dikirim harus memiliki metode untuk kelas objek tersebut. Sebagai contoh adalah kita menggunakan kode ini dengan mean
fungsi kita akan memiliki kode ini yang tidak masuk akal sama sekali:
by(iris, iris$Species, mean)
iris$Species: setosa
[1] NA
-------------------------------------------
iris$Species: versicolor
[1] NA
-------------------------------------------
iris$Species: virginica
[1] NA
Warning messages:
1: In mean.default(data[x, , drop = FALSE], ...) :
argument is not numeric or logical: returning NA
2: In mean.default(data[x, , drop = FALSE], ...) :
argument is not numeric or logical: returning NA
3: In mean.default(data[x, , drop = FALSE], ...) :
argument is not numeric or logical: returning NA
AGREGAT
aggregate
dapat dilihat sebagai cara penggunaan yang berbeda tapply
jika kita menggunakannya sedemikian rupa.
at <- tapply(iris$Sepal.Length , iris$Species , mean)
ag <- aggregate(iris$Sepal.Length , list(iris$Species), mean)
at
setosa versicolor virginica
5.006 5.936 6.588
ag
Group.1 x
1 setosa 5.006
2 versicolor 5.936
3 virginica 6.588
Dua perbedaan langsung adalah bahwa argumen kedua aggregate
harus daftar sementara tapply
bisa (tidak wajib) menjadi daftar dan bahwa output aggregate
adalah bingkai data sedangkan yang salah tapply
adalah array
.
Kekuatannya aggregate
adalah ia dapat menangani subset data dengan mudah dengan subset
argumen dan memiliki metode untuk ts
objek dan formula
juga.
Elemen-elemen ini aggregate
memudahkan untuk bekerja dengan itu tapply
dalam beberapa situasi. Berikut adalah beberapa contoh (tersedia dalam dokumentasi):
ag <- aggregate(len ~ ., data = ToothGrowth, mean)
ag
supp dose len
1 OJ 0.5 13.23
2 VC 0.5 7.98
3 OJ 1.0 22.70
4 VC 1.0 16.77
5 OJ 2.0 26.06
6 VC 2.0 26.14
Kita dapat mencapai hal yang sama dengan tapply
tetapi sintaks sedikit lebih sulit dan output (dalam beberapa keadaan) kurang dapat dibaca:
att <- tapply(ToothGrowth$len, list(ToothGrowth$dose, ToothGrowth$supp), mean)
att
OJ VC
0.5 13.23 7.98
1 22.70 16.77
2 26.06 26.14
Ada saat-saat lain ketika kita tidak dapat menggunakan by
atau tapply
dan kita harus menggunakannya aggregate
.
ag1 <- aggregate(cbind(Ozone, Temp) ~ Month, data = airquality, mean)
ag1
Month Ozone Temp
1 5 23.61538 66.73077
2 6 29.44444 78.22222
3 7 59.11538 83.88462
4 8 59.96154 83.96154
5 9 31.44828 76.89655
Kami tidak dapat memperoleh hasil sebelumnya dengan tapply
satu panggilan, tetapi kami harus menghitung rata-rata Month
untuk setiap elemen dan kemudian menggabungkannya (juga perhatikan bahwa kami harus memanggil na.rm = TRUE
, karena formula
metode aggregate
fungsi secara default na.action = na.omit
):
ta1 <- tapply(airquality$Ozone, airquality$Month, mean, na.rm = TRUE)
ta2 <- tapply(airquality$Temp, airquality$Month, mean, na.rm = TRUE)
cbind(ta1, ta2)
ta1 ta2
5 23.61538 65.54839
6 29.44444 79.10000
7 59.11538 83.90323
8 59.96154 83.96774
9 31.44828 76.90000
sementara dengan by
kita tidak bisa mencapai itu pada kenyataannya panggilan fungsi berikut mengembalikan kesalahan (tetapi kemungkinan besar itu terkait dengan fungsi yang disediakan, mean
):
by(airquality[c("Ozone", "Temp")], airquality$Month, mean, na.rm = TRUE)
Lain kali hasilnya sama dan perbedaannya hanya di kelas (dan kemudian bagaimana itu ditampilkan / dicetak dan tidak hanya - contoh, cara subset itu) objek:
byagg <- by(airquality[c("Ozone", "Temp")], airquality$Month, summary)
aggagg <- aggregate(cbind(Ozone, Temp) ~ Month, data = airquality, summary)
Kode sebelumnya mencapai tujuan dan hasil yang sama, pada beberapa titik alat apa yang digunakan hanyalah masalah selera dan kebutuhan pribadi; dua objek sebelumnya memiliki kebutuhan yang sangat berbeda dalam hal pengaturan ulang.
*apply()
danby
. plyr (setidaknya bagi saya) tampaknya jauh lebih konsisten karena saya selalu tahu persis format data apa yang diharapkannya dan apa yang akan dimuntahkannya. Itu menyelamatkan saya banyak kerumitan.