R是一個面向科學工程計算特別是統計計算的工具。與matlab一樣,其循環結構的效率也無法讓人滿意。在平常的編程過程中我們應該儘量避免使用循環,而採用向量化的編程語法可以幫助我們有效提高數據處理效率。本文我們主要介紹如何使用R語言中的apply家族函數來實現向量化運算。
為了更好的理解apply家族函數的用法,本文需要用到mtcars數據集和beavers數據集。
#mtcars數據集是從1974年 Motor Trend Us 雜誌採集到的,數據集的列由油耗以及汽車設計的10個方面共計11個變量組成,共有32條記錄。data("mtcars")head(mtcars) mpg cyl disp hp drat wt qsec vs am gear carbMazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1# beavers數據是對海狸的體溫測量數據data(beavers)head(t(beaver1)[1:4,1:10]) [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]day 346.00 346.00 346.00 346.00 346.00 346.00 346.00 346.00 346.00 346.00time 840.00 850.00 900.00 910.00 920.00 930.00 940.00 950.00 1000.00 1010.00temp 36.33 36.34 36.35 36.42 36.55 36.69 36.71 36.75 36.81 36.88activ 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
apply()函數apply()函數的調用格式為apply(X, MARGIN, FUN, ...),其中:
案例演示:
#按行計算最大值apply(t(beaver1),1,max) day time temp activ 347.00 2350.00 37.53 1.00 #按列計算均值apply(mtcars,2,mean) mpg cyl disp hp drat wt qsec vs am gear carb 20.090625 6.187500 230.721875 146.687500 3.596563 3.217250 17.848750 0.437500 0.406250 3.687500 2.812500 #將數據集按列運用到自定義函數上head(apply(mtcars,2,function(x) x%%10)) mpg cyl disp hp drat wt qsec vs am gear carbMazda RX4 1.0 6 0 0 3.90 2.620 6.46 0 1 4 4Mazda RX4 Wag 1.0 6 0 0 3.90 2.875 7.02 0 1 4 4Datsun 710 2.8 4 8 3 3.85 2.320 8.61 1 1 4 1Hornet 4 Drive 1.4 6 8 0 3.08 3.215 9.44 1 0 3 1Hornet Sportabout 8.7 8 0 5 3.15 3.440 7.02 0 0 3 2Valiant 8.1 6 5 5 2.76 3.460 0.22 1 0 3 1
lapply()函數lapply()函數的調用格式為lapply(X, FUN, ...),結果的返回是list類型,其組件長度跟X的組件長度相同。其中:
X:list對象
FUN:調用的函數
...:是FUN函數的可選參數
創建組件長度為2的列表l = list(a=1:10,b=11:20) #對每個組件求均值lapply(l, mean)$a[1] 5.5$b[1] 15.5#查看返回結果的數據類型class(lapply(l, mean))[1] "list#對每個組件求和lapply(l, sum)$a[1] 55$b[1] 155
sapply()函數sapply()函數是lapply()函數的一個更加友好版本,它實現了對lapply()函數的封裝。返回的結果是一個向量或矩陣
l = list(a=1:10,b=11:20) # mean of values using sapply sapply(l, mean) a b 5.5 15.5
tapply()函數tapply()函數的作用是先將數據分為若干組,然後在每組數據調用指定的函數。函數調用格式為tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE),其中:
#查看數據結構str(mtcars$cyl) num [1:32] 6 6 4 6 8 6 8 4 4 6 ...levels(as.factor(mtcars$cyl))[1] "4" "6" "8"tapply(mtcars$mpg,mtcars$cyl,mean) 4 6 8 26.66364 19.74286 15.10000
mtcars數據集中的列cyl共有三種汽車氣缸類型,tapply()函數會自動將數值型向量其轉為因子類型,最後對每種汽缸數類型的汽車每加侖汽油行駛裡程數求平均值。
by()函數如上所述,tapply()函數中的參數X只能是一個向量,而by()函數很好的實現了對tapply()函數的封裝,使得傳入的數據可以是數據框或矩陣。調用格式為by(data, INDICES, FUN, ..., simplify = TRUE)。其中:
data(iris) str(iris)'data.frame': 150 obs. of 5 variables: $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...by(iris[,1:4],iris$Species,colMeans)iris$Species: setosaSepal.Length Sepal.Width Petal.Length Petal.Width 5.006 3.428 1.462 0.246 ---- iris$Species: versicolorSepal.Length Sepal.Width Petal.Length Petal.Width 5.936 2.770 4.260 1.326 ---- iris$Species: virginicaSepal.Length Sepal.Width Petal.Length Petal.Width 6.588 2.974 5.552 2.026
本文連結http://www.xueqing.tv/cms/article/158
文章來源:雪晴數據網