R:申请vs do.call

Hel*_*len 7 r apply do.call

我刚刚阅读了@David Arenburg的个人资料,并找到了一些关于如何培养良好的R编程技巧/习惯的有用技巧,其中一个特别令我印象深刻.我一直认为R中的apply函数是处理数据帧的基石,但他写道:

如果您正在使用data.frames,请忘记有一个名为apply的函数 - 无论您做什么 - 都不要使用它.特别是边距为1(此功能的唯一好用途是在矩阵列上操作 - 边距为2).

一些好的选择:?do.call,?pmax/pmin,?max.col,?rowSums/rowMeans/etc,令人敬畏的matrixStats包(用于矩阵),?rowsum等等

有人可以向我解释一下吗?为什么申请职能不受欢迎?

G. *_*eck 5

  • apply(DF, 1, f)将的每一行转换DF为一个向量,然后将该向量传递给f。如果DF混合使用字符串和数字,则该行在传递给它之前将被转换为字符向量f,例如,apply(iris, 1, function(x) sum(x[-5]))即使该行iris[i, -5]包含所有数字元素,该行也将不起作用。该行将转换为字符串,并且您不能对字符串求和。另一方面apply(iris[-5], 1, sum)将与相同rowSums(iris[-5])

  • 如果f产生向量,则结果是矩阵而不是另一个数据帧;同样,结果就是您可能期望的转置。这个

    apply(BOD, 1, identity)
    
    Run Code Online (Sandbox Code Playgroud)

    提供以下内容,而不是BOD回馈:

           [,1] [,2] [,3] [,4] [,5] [,6]
    Time    1.0  2.0    3    4  5.0  7.0
    demand  8.3 10.3   19   16 15.6 19.8
    
    Run Code Online (Sandbox Code Playgroud)

    许多年前哈德利韦翰做 iapply是幂等在这个意义上iapply(mat, 1, identity)的回报mat,而不是t(mat),这里mat是一个矩阵。最近,他的plyr包可以写:

    library(plyr)
    ddplyr(BOD, 1, identity)
    
    Run Code Online (Sandbox Code Playgroud)

    BOD作为数据框返回。

另一方面,apply(BOD, 1, sum)将给出与产生相同标量的函数相同的结果,rowSums(BOD)并且apply(BOD, 1, f)可能ff产生标量的函数有用,并且在sum/ rowSumscase中没有对应的结果。同样,如果f产生向量并且您不介意矩阵结果,则可以对apply自己的输出进行转置,尽管它很丑陋。