R编程中的apply(),sapply(),lapply()和tapply()函数
R中的apply()函数族用于将用户定义的函数应用于复杂结构的元素,如矩阵,列表或者数据帧。
这些功能在简化代码和提高可读性方面有很大帮助。
而且,它们也与并行处理兼容。
让我们用详细的示例看一下每个函数。
R编程中的apply()函数
R中的apply()函数用于矩阵的情况下,以将用户指定的函数应用于矩阵的行或者列。
以下是apply()函数的常规语法。
apply(matrix, code, f, fargs) </code>
在上述形式中,"矩阵"是我们使用apply()函数的矩阵对象。
"代码"表示我们是否希望将函数应用于行(代码设置为1)或者列(代码设置为2)。
F代表我们需要应用的函数,而fars是传递给该函数的参数。
让我们首先定义一个矩阵来说明apply()函数。
> x <-matrix(c(4,5,6,10,12,16),nrow=2,ncol=3) > x [,1] [,2] [,3] [1,] 4 6 12 [2,] 5 10 16 </code>
假设我们希望对每个元素执行非常特定的功能,例如先平方,然后除以3再乘以4。
让我们定义一个执行此功能的函数。
> f <-function(x) + { + return (x^2*3/4) + } > f(5) [1] 18.75 </code>
现在,为了将此函数应用于矩阵中的所有行/列,我们调用apply()函数。
> apply(x, 2, f) [,1] [,2] [,3] [1,] 12.00 27 108 [2,] 18.75 75 192 </code>
该函数可以方便地应用于矩阵中的每个元素,而无需在循环中调用它。
R中的apply()函数不会在执行速度方面带来任何好处,但可以帮助您编写更简洁,更紧凑的代码。
R编程中的sapply()和lapply()函数
使用列表
R中的lapply()
函数是列表应用的缩写。
它的工作方式类似于上面的apply()
函数,但是使用列表而不是矩阵。
让我们看一个例子:
> mylist <- list(c(1,2,3,4),c(10,20,30,40),c(5,5,5,5)) > lapply(mylist,mean) [[1]] [1] 2.5 [[2]] [1] 25 [[3]] [1] 5 </code>
列表mylist是3个向量的列表。
我们希望对每个向量应用均值函数。
这是通过调用lapply(mylist,mean)来完成的,该函数返回三个组成矢量的平均值。
同样,R中的sapply()函数是简化应用的简称。
而不是为每个向量获取单独的平均值,sapply
返回包含平均值的向量。
> sapply(mylist,mean) [1] 2.5 25.0 5.0 </code>
在R中使用数据框
由于数据帧可以视为列表的特殊情况,因此函数lapply()和sapply()在两种情况下都可以工作。
让我们来看一个例子。
让我们先创建一个数据帧,然后使用R中的lapply()函数在其上应用sort()函数。
names <- c("Adam","Antony","Brian","Carl","Doug") ages <- c(23,22,24,25,26) playerdata <- data.frame(names,ages,stringsAsFactors = FALSE) #Apply a sort function on the dataframe > lapply(playerdata,sort) $names [1] "Adam" "Antony" "Brian" "Carl" "Doug" $ages [1] 22 23 24 25 26 </code>
该函数分别按排序顺序返回数据框的两列。
同样,调用sapply()会提供一个紧凑的列表,其中每个列都单独排序。
> sapply(playerdata,sort) names ages [1,] "Adam" "22" [2,] "Antony" "23" [3,] "Brian" "24" [4,] "Carl" "25" [5,] "Doug" "26" </code>
tapply()函数
tapply()函数也属于同一家族,但仅在有因素的情况下使用。
最好用一个例子来解释。
假设我们以矢量的形式获取中员工的薪水,并将其各自的运输方式作为一个因子。
假设我们希望使用特定的运输方式来计算每个组的平均工资。
为此,可以使用R的内置均值函数来调用R编程中的tapply()函数。
> salaries <-c(25000,30000,45000,66000,20000,50000,35000,20000,15000) > transport <-c('Bus','Car','Bus','Car','Metro','Metro','Bus','Bus','Metro') > tapply(salaries,transport,mean) Bus Car Metro 31250.00 48000.00 28333.33 </code>
如您所见,R中的tapply()函数以一种运输方式作为列输出格式合理的薪水平均值。
另外,请注意它是如何仅自动考虑传输向量中的唯一值的。