4 回答

TA貢獻(xiàn)1878條經(jīng)驗(yàn) 獲得超4個贊
首先從Joran的優(yōu)秀答案開始 - 懷疑任何事情都可以更好。
然后,以下助記符可能有助于記住每個之間的區(qū)別。雖然有些是顯而易見的,但有些可能不那么明顯 - 對于這些,你會在Joran的討論中找到理由。
助記符
lapply
是一個列表應(yīng)用,它作用于列表或向量并返回一個列表。sapply
是一個簡單的lapply
(函數(shù)默認(rèn)為在可能的情況下返回向量或矩陣)vapply
是經(jīng)過驗(yàn)證的申請(允許預(yù)先指定退貨對象類型)rapply
是嵌套列表的遞歸應(yīng)用,即列表中的列表tapply
是標(biāo)記應(yīng)用,其中標(biāo)記標(biāo)識子集apply
是 通用的:應(yīng)用一個函數(shù)的矩陣的行或列(或者,更一般地,以陣列的尺寸)
建立正確的背景
如果使用這個apply
家庭仍然覺得你有點(diǎn)陌生,那么可能是你錯過了一個關(guān)鍵的觀點(diǎn)。
這兩篇文章可以提供幫助。它們提供了激發(fā)函數(shù)apply
族提供的函數(shù)式編程技術(shù)的必要背景。
Lisp的用戶將立即認(rèn)識到這種范式。如果你不熟悉Lisp,一旦你了解了FP,你就會獲得一個強(qiáng)大的觀點(diǎn)來使用R - 并且apply
會更有意義。
高級R:功能編程,由Hadley Wickham撰寫
R的簡單函數(shù)式編程,作者:Michael Barton

TA貢獻(xiàn)1847條經(jīng)驗(yàn) 獲得超11個贊
因?yàn)槲乙庾R到這篇文章的(非常優(yōu)秀的)答案缺乏by和aggregate解釋。這是我的貢獻(xiàn)。
通過
by但是,如文檔中所述,該函數(shù)可以作為“包裝器” tapply。by當(dāng)我們想要計(jì)算tapply無法處理的任務(wù)時,會產(chǎn)生這種力量。一個例子是這段代碼:
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
如果我們打印這兩個對象,ct并且cb我們“基本上”具有相同的結(jié)果,唯一的區(qū)別在于它們的顯示方式和不同的class屬性,分別by為for cb和arrayfor ct。
正如我所說,by當(dāng)我們不能使用時會產(chǎn)生力量tapply; 以下代碼是一個例子:
tapply(iris, iris$Species, summary )
Error in tapply(iris, iris$Species, summary) :
arguments must have same length
R表示參數(shù)必須具有相同的長度,比如“我們想要計(jì)算沿著因子summary的所有變量”:但是R不能這樣做,因?yàn)樗恢廊绾翁幚?。irisSpecies
使用by函數(shù)R為data frame類調(diào)度一個特定的方法,然后讓summary函數(shù)工作,即使第一個參數(shù)(和類型)的長度不同。
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
它確實(shí)有效,結(jié)果非常令人驚訝。這是一個類的對象by,沿著Species(例如,對于每個類)計(jì)算summary每個變量。
請注意,如果第一個參數(shù)是a data frame,則dispatched函數(shù)必須具有該類對象的方法。例如,我們將此代碼與mean函數(shù)一起使用,我們將擁有完全沒有意義的代碼:
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
骨料
aggregatetapply如果我們以這種方式使用它,可以被視為另一種不同的使用方式。
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
兩個直接的區(qū)別是第二個參數(shù)aggregate 必須是一個列表,而tapply can(非強(qiáng)制性)是一個列表,輸出aggregate是一個數(shù)據(jù)幀,而一個tapply是array。
它的強(qiáng)大之a(chǎn)ggregate處在于它可以使用subset參數(shù)輕松處理數(shù)據(jù)的子集,并且它還具有ts對象的方法formula。
在某些情況下aggregate,這些元素更容易使用tapply。以下是一些示例(可在文檔中找到):
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
我們可以實(shí)現(xiàn)相同,tapply但語法稍微困難,輸出(在某些情況下)可讀性較差:
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
還有一些時候我們不能使用by或者tapply我們必須使用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在一次調(diào)用中獲得先前的結(jié)果,但我們必須計(jì)算Month每個元素的平均值然后將它們組合起來(還要注意我們必須調(diào)用它na.rm = TRUE,因?yàn)楹瘮?shù)的formula方法aggregate默認(rèn)情況下是這樣的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
雖然by我們實(shí)際上無法實(shí)現(xiàn),但實(shí)際上以下函數(shù)調(diào)用會返回錯誤(但很可能與提供的函數(shù)有關(guān)mean):
by(airquality[c("Ozone", "Temp")], airquality$Month, mean, na.rm = TRUE)
其他時候結(jié)果是相同的,差異只是在類中(然后它是如何顯示/打印的,而不僅僅是 - 例如,如何將其子集化)對象:
byagg <- by(airquality[c("Ozone", "Temp")], airquality$Month, summary)
aggagg <- aggregate(cbind(Ozone, Temp) ~ Month, data = airquality, summary)
以前的代碼實(shí)現(xiàn)了相同的目標(biāo)和結(jié)果,在某些方面,使用的工具只是個人品味和需求的問題; 前兩個對象在子集方面有非常不同的需求。
- 4 回答
- 0 關(guān)注
- 2044 瀏覽
添加回答
舉報(bào)