apply 和 sapply 数据框列之间的区别?

Difference between apply and sapply for data frame columns?

有人可以解释一下 apply()sapply() 如何对数据框的 进行操作的区别吗?

例如,在尝试查找数据框中每一列的 class 时,我的第一个倾向是在列上使用 apply

> apply(iris, 2, class)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
 "character"  "character"  "character"  "character"  "character" 

然而,这是不正确的,因为有些列是数字的:

> class(iris$Petal.Length)
[1] "numeric"

在 Google 上快速搜索 this solution 找到了使用 sapply 而不是 apply 的问题:

> sapply(iris, class)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
   "numeric"    "numeric"    "numeric"    "numeric"     "factor"

在这种情况下,sapply 隐式地将 iris 转换为列表,然后将函数应用于列表中的每个条目,例如:

> class(as.list(iris)$Petal.Length)
[1] "numeric"

我仍然不清楚的是为什么我最初使用 apply 的尝试没有奏效。

就像经常出现的情况一样,我在撰写问题的过程中找到了问题的答案。在这里发布答案以防其他人有同样的问题。

仔细观察 ?apply 状态:

If ‘X’ is not an array but an object of a class with a non-null ‘dim’ value (such as a data frame), ‘apply’ attempts to coerce it to an array via ‘as.matrix’ if it is two-dimensional (e.g., a data frame) or via ‘as.array’.

因此,就像 sapply 在对其进行操作之前将数据帧转换为 list 一样,apply 将数据帧转换为 matrix。由于矩阵不能有混合类型,并且至少有一列是非数字数据(Species),所以一切都变成字符数据:

> class(as.matrix(iris)[,'Petal.Length'])
[1] "character"