R語言基礎系列:
- R語言基礎1--R數據格式:.rds和.rda的區別
- R語言基礎2--數據排序與長寬型數據的轉換
- R語言基礎3--tidyverse包總結
- R語言基礎4--dplyr包的函數及用法
- R語言基礎5--tidyr包的函數及用法
apply函數家族是R語言中數據處理的一組核心函數,通過使用apply函數,我們可以實現對數據的循環、分組、過濾、類型控制等操作。
apply函數本身是用來解決數據循環處理的問題,為了面向不同的數據類型,不同的返回值,apply函數組成了一個函數加族,包括了8個功能類似的函數。
下面將分別介紹這幾個函數的定義和使用方法。
1. apply函數
apply函數是最常用的代替for循環的函數。apply函數可以對矩陣
、數據框
、數組
(二維、多維),,對子元素進行迭代,并把子元素以參數傳遞的形式給自定義的FUN函數中,并以返回計算結果。
1.1 函數定義:
apply(X, MARGIN, FUN, ...)
1.2 參數列表:
X:數組、矩陣、數據框
MARGIN:按行計算或按按列計算,1表示按行,2表示按列
FUN:自定義的調用函數
…:更多參數,可選
1.3 應用:
# 對一個矩陣的每一列求和
# 生成data.frame
> x <- cbind(x1 = 3, x2 = c(4:1, 2:5)); x
x1 x2
[1,] 3 4
[2,] 3 3
[3,] 3 2
[4,] 3 1
[5,] 3 2
[6,] 3 3
[7,] 3 4
[8,] 3 5
apply(x,2,sum)
# x1 x2
# 24 24
apply(x,1,mean)
# [1] 3.5 3.0 2.5 2.0 2.5 3.0 3.5 4.0
2. lapply函數
lapply函數是一個最基礎循環操作函數之一,用來對list
、data.frame
數據集進行循環,并作為結果集,通過lapply的開頭的第一個字母’l’就可以判斷返回結果集的類型。
2.1 函數定義
lapply(X, FUN, ...)
2.2 參數列表
X:list、data.frame數據
FUN:自定義的調用函數
…:更多參數,可選
2.3 應用
輸入list,返回對每個list進行操作后的list。
# 構建一個list數據集x,分別包括a,b,c 三個KEY值。
x <- list(a = 1:10, b = rnorm(6,10,5), c = c(TRUE,FALSE,FALSE,TRUE));x
# $a
# [1] 1 2 3 4 5 6 7 8 9 10
# $b
# [1] 9.186837 7.372569 9.942975 16.946282 2.550059
# [6] 6.991188
# $c
# [1] TRUE FALSE FALSE TRUE
# 分別計算每個KEY對應該的數據的分位數。
lapply(x,fivenum)
# $a
# [1] 1.0 3.0 5.5 8.0 10.0
# $b
# [1] 2.550059 6.991188 8.279703 9.942975 16.946282
# $c
# [1] 0.0 0.0 0.5 1.0 1.0
如果輸入的是數據框,lapply會自動把數據框按列進行分組,再進行計算。
lapply(data.frame(x), sum)
$x1
[1] 12
$x2
[1] 12
lapply可以很方便地對list數據集中個每個list進行循環操作,還可以用data.frame數據集按列進行循環,但如果傳入的數據集是一個向量或矩陣對象,那么直接使用lapply就不能達到想要的效果了。lapply會分別循環矩陣中的每個值,而不是按行或按列進行分組計算。
x <- cbind(x1=3, x2=c(2:1,4:5))
x; class(x)
# x1 x2
# [1,] 3 2
# [2,] 3 1
# [3,] 3 4
# [4,] 3 5
# [1] "matrix" "array"
lapply(x, sum)
# [[1]]
# [1] 3
# [[2]]
# [1] 3
# [[3]]
# [1] 3
# [[4]]
# [1] 3
# [[5]]
# [1] 2
# [[6]]
# [1] 1
# [[7]]
# [1] 4
# [[8]]
# [1] 5
3. sapply函數
sapply函數是一個簡化版的lapply,sapply增加了2個參數simplify和USE.NAMES,主要就是讓輸出看起來更友好,與lapply不同的是,,而不是list對象。
3.1 函數定義
sapply(X, FUN, ..., simplify=TRUE, USE.NAMES = TRUE)
3.2 參數列表
X:數組、矩陣、數據框
FUN:自定義的調用函數
…:更多參數,可選
simplify:是否數組化,當設置simplify='array'時,輸出結果按數組進行分組
USE.NAMES:如果X為字符串,TRUE設置字符串為數據名,FALSE不設置
3.3 應用
x <- cbind(x1=3, x2=c(2:1,4:5))
# 對矩陣計算,計算過程同lapply函數
sapply(x, sum)
# [1] 3 3 3 3 2 1 4 5
# 對數據框計算
sapply(data.frame(x), sum)
# x1 x2
# 12 12
# 檢查結果類型,sapply返回類型為向量,而lapply的返回類型為list
class(lapply(x, sum))
# [1] "list"
class(sapply(x, sum))
# [1] "numeric"
如果simplify=FALSE和USE.NAMES=FALSE,那么完全sapply函數就等于lapply函數了。
sapply(data.frame(x), sum, simplify=FALSE, USE.NAMES=FALSE)
# $x1
# [1] 12
# $x2
# [1] 12
對于simplify為array時,我們可以參考下面的例子,構建一個三維數組,其中二個維度為方陣。
a<-1:2
# 按數組分組
sapply(a,function(x) matrix(x,2,2), simplify='array')
# , , 1
# [,1] [,2]
# [1,] 1 1
# [2,] 1 1
# , , 2
# [,1] [,2]
# [1,] 2 2
# [2,] 2 2
# 默認情況,則自動合并分組
sapply(a,function(x) matrix(x,2,2))
# [,1] [,2]
# [1,] 1 2
# [2,] 1 2
# [3,] 1 2
# [4,] 1 2
對于字符串的向量,還可以自動生成數據名。
val<-head(letters)
# 默認設置數據名
sapply(val,paste,USE.NAMES=TRUE)
# a b c d e f
# "a" "b" "c" "d" "e" "f"
# USE.NAMES=FALSE,則不設置數據名
sapply(val,paste,USE.NAMES=FALSE)
# [1] "a" "b" "c" "d" "e" "f"
4. tapply函數
tapply用于分組的循環計算,通過INDEX參數(分類變量)對數據集X進行分組并計算分組計算,相當于group by的操作。
4.1 函數定義
tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE)
4.2 參數列表
X:向量
INDEX:用于分組的索引
FUN:自定義的調用函數
…:接收多個數據
simplify:是否數組化,當值array時,輸出結果按數組進行分組
4.3 應用
#計算不同品種(Species)的鳶尾花(iris)的花瓣長度(Petal.Length)的均值。
tapply(X = iris$Petal.Length,INDEX = iris$Species,FUN = mean)
# setosa versicolor virginica
# 1.462 4.260 5.552
5. mapply函數
mapply也是sapply的變形函數,類似多變量的sapply,但是參數定義有些變化。第一參數為自定義的FUN函數,第二個參數’…’可以接收多個數據,作為FUN函數的參數調用。
5.1 函數定義
mapply(FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE,USE.NAMES = TRUE)
5.2 參數列表
FUN:自定義的調用函數
…:接收多個數據
MoreArgs:參數列表
SIMPLIFY:是否數組化,當值array時,輸出結果按數組進行分組
USE.NAMES:如果X為字符串,TRUE設置字符串為數據名,FALSE不設置
5.3 應用
比如,比較3個向量大小,按索引順序取較大的值。
set.seed(1)
# 定義3個向量
x<-1:10
y<-5:-4
z<-round(runif(10,-5,5))
# 按索引順序取較大的值。
mapply(max,x,y,z)
# [1] 5 4 3 4 5 6 7 8 9 10
再看一個例子,生成4個符合正態分布的數據集,分別對應的均值和方差為c(1,10,100,1000)。
set.seed(1)
# 長度為4
n<-rep(4,4)
# m為均值,v為方差
m<-v<-c(1,10,100,1000)
# 生成4組數據,按列分組
mapply(rnorm,n,m,v)
# [,1] [,2] [,3] [,4]
# [1,] 0.3735462 13.295078 157.57814 378.7594
# [2,] 1.1836433 1.795316 69.46116 -1214.6999
# [3,] 0.1643714 14.874291 251.17812 2124.9309
# [4,] 2.5952808 17.383247 138.98432 955.0664
由于mapply是可以接收多個參數的,所以我們在做數據操作的時候,就不需要把數據先合并為data.frame了,直接一次操作就能計算出結果了。
參考:https://blog.csdn.net/u012108367/article/details/80774977