R编程中的apply(),sapply(),lapply()和tapply()函数

时间:2020-02-23 14:43:47  来源:igfitidea点击:

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()函数以一种运输方式作为列输出格式合理的薪水平均值。
另外,请注意它是如何仅自动考虑传输向量中的唯一值的。