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

Kei*_*itt 4 r apply dataframe sapply

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

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

> apply(iris, 2, class)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
 "character"  "character"  "character"  "character"  "character" 
Run Code Online (Sandbox Code Playgroud)

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

> class(iris$Petal.Length)
[1] "numeric"
Run Code Online (Sandbox Code Playgroud)

在 Google 上进行快速搜索,找到了问题的解决方案该解决方案使用sapply而不是apply

> sapply(iris, class)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
   "numeric"    "numeric"    "numeric"    "numeric"     "factor"
Run Code Online (Sandbox Code Playgroud)

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

> class(as.list(iris)$Petal.Length)
[1] "numeric"
Run Code Online (Sandbox Code Playgroud)

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

Kei*_*itt 5

与往常一样,我在写问题的过程中找到了问题的答案。在这里发布答案,以防其他人有同样的问题。

仔细看看?apply状态:

如果“X”不是数组而是具有非空“dim”值的类的对象(例如数据框),则“apply”尝试通过“as.matrix”将其强制转换为数组(如果是)二维(例如,数据框)或通过“as.array”。

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

> class(as.matrix(iris)[,'Petal.Length'])
[1] "character"
Run Code Online (Sandbox Code Playgroud)