Bu yazının (çok mükemmel) cevaplarının eksikliğini by
ve aggregate
açıklamalarını fark ettiğimden beri . İşte katkım.
TARAFINDAN
by
Olarak belgelerinde belirtildiği fonksiyon, bir "sargı" gibi olsa da olabilir tapply
. by
İşleyemediğimiz bir görevi hesaplamak istediğimiz zaman ortaya çıkan güç ortaya çıkar tapply
. Bir örnek bu kod:
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
Bu iki nesne yazdırmak, varsa ct
ve cb
biz "esasen" aynı sonuçları ve sadece farklılıkları nasıl gösterilir ve farklı olan class
sırasıyla nitelikler by
için cb
ve array
için ct
.
Söylediğim gibi, by
kullanamadığımız zaman ortaya çıkan güç tapply
; aşağıdaki kod bir örnektir:
tapply(iris, iris$Species, summary )
Error in tapply(iris, iris$Species, summary) :
arguments must have same length
R, argümanların aynı uzunluklara sahip olması gerektiğini söylüyor: " summary
tüm değişkenin iris
faktör boyunca hesaplanmasını istiyoruz Species
": ancak R bunu yapamaz çünkü nasıl ele alınacağını bilmez.
İle by
fonksiyonu, R için özel bir yöntem sevk data frame
sınıf ve daha sonra izin summary
fonksiyonu ilk bağımsız değişken uzunluk (ve çok tipi) farklı olsa bile çalışır.
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
gerçekten işe yarıyor ve sonuç çok şaşırtıcı. Her değişkenin by
birlikte Species
(örneğin her biri için) hesapladığı bir sınıf nesnesidir summary
.
İlk bağımsız değişken a data frame
ise, gönderilen işlevin bu nesne sınıfı için bir yöntemi olması gerektiğini unutmayın. Örneğin mean
, bu kodu, hiçbir anlamı olmayan bu koda sahip olacağımız işlevle kullanıyoruz :
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
AGREGA
aggregate
bu şekilde kullanırsak başka bir kullanım şekli olarak görülebilir tapply
.
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
İki yakın fark ikinci argüman, olan aggregate
gerekir ise bir liste tapply
kutusu (zorunlu değil) bir liste ve çıkış olduğu aggregate
bir süre bir veri çerçevesi olan tapply
bir bir array
.
Bunun gücü aggregate
, verilerin alt kümelerini subset
argümanla kolayca işleyebilmesidir ve ts
nesneler için de yöntemlere sahip olmasıdır formula
.
Bu öğeler bazı durumlarda aggregate
bununla çalışmayı kolaylaştırır tapply
. İşte bazı örnekler (belgelerde mevcuttur):
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
Aynı şeyi elde edebiliriz tapply
ancak sözdizimi biraz daha zor ve çıktı (bazı durumlarda) daha az okunabilir:
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
Orada kullanamayan diğer zamanlar by
ya tapply
ve biz kullanmak zorunda 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
tapply
Bir aramada önceki sonucu elde edemiyoruz, ancak Month
her eleman için ortalamayı hesaplamamız ve sonra birleştirmemiz gerekiyor (ayrıca , işlevin yöntemleri varsayılan olarak the'e sahip na.rm = TRUE
olduğu için, şunu çağırmamız gerektiğini unutmayın ):formula
aggregate
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
Bununla birlikte by
, aslında aşağıdaki işlev çağrısının bir hata döndürdüğünü başaramayız (ancak büyük olasılıkla sağlanan işlevle ilgilidir mean
):
by(airquality[c("Ozone", "Temp")], airquality$Month, mean, na.rm = TRUE)
Diğer zamanlarda sonuçlar aynıdır ve farklılıklar sadece sınıfta (ve daha sonra nasıl gösterildiğini / yazdırıldığını ve sadece - değil, nasıl alt kümeleneceğini) nesnesindedir:
byagg <- by(airquality[c("Ozone", "Temp")], airquality$Month, summary)
aggagg <- aggregate(cbind(Ozone, Temp) ~ Month, data = airquality, summary)
Önceki kod aynı hedefe ve sonuçlara ulaşır, bazı noktalarda hangi aracın kullanılacağı sadece kişisel zevkler ve ihtiyaçlar meselesidir; önceki iki nesnenin alt kümeleme açısından çok farklı ihtiyaçları vardır.
*apply()
ve yerine doğrudan bir alternatiftirby
. plyr (en azından benim için) her zaman tam olarak hangi veri formatını beklediğini ve tam olarak ne tüküreceğini bildiğimden çok daha tutarlı görünüyor. Bu bana çok fazla güçlük kazandırıyor.