【问题标题】:Apply function to every value in an R dataframe将函数应用于 R 数据框中的每个值
【发布时间】:2021-10-12 14:10:57
【问题描述】:

我有一个 58 列的数据框,我需要将转换 $log(x_{i,j}+1)$ 应用于前 56 列中的所有值。我可以使用什么方法最有效地解决这个问题?我假设有一些东西可以让我这样做,而不仅仅是使用一些 for 循环来运行整个数据帧。

【问题讨论】:

    标签: r


    【解决方案1】:

    alexwhan 的答案对于 log 是正确的(并且可能应该被选为正确的答案)。但是,它工作得非常干净,因为日志是矢量化的。我太频繁地经历了非向量化函数的特殊痛苦。当我开始使用 R 并且不太了解 apply 系列时,我经常使用丑陋的循环。因此,对于那些可能偶然发现这个问题但没有矢量化函数的人,我提供了以下概念证明。

    #Creating sample data
    df <- as.data.frame(matrix(runif(56 * 56), 56, 56))
    #Writing an ugly non-vectorized function
    logplusone <- function(x) {log(x[1] + 1)}
    #example code that achieves the desired result, despite the lack of a vectorized function
    df[, 1:56] <- as.data.frame(lapply(df[, 1:56], FUN = function(x) {sapply(x, FUN = logplusone)}))
    #Proof that the results are the same using both methods... 
    #Note: I used all.equal rather than all so that the values are tested using machine tolerance for mathematical equivalence.  This is probably a non-issue for the current example, but might be relevant with some other testing functions.
    #should evaluate to true
    all.equal(log(df[, 1:56] + 1),as.data.frame(lapply(df[, 1:56], FUN = function(x) {sapply(x, FUN = logplusone)}))) 
    

    【讨论】:

    • 请注意,尽管它不适用于您的特定示例 - 您有时可以通过运行 Vectorize 函数来绕过未矢量化的函数。
    • 虽然如果你将它加倍矢量化它会起作用,例如向量化(向量化(logplusone,"x"),"x")
    • ... 但是,我发现 Vectorized 函数有点难以阅读,所以我更喜欢我的答案中提出的解决方案,因为它对我来说更容易(当我回到代码)来弄清楚它是如何工作的。
    • 真的吗?我发现矢量化代码比 sapply 代码更容易阅读。对于您的示例代码,解析您实际在做什么需要做更多的工作-“好的,所以我们想在数据框的列上应用...好的,然后我们想在每个列上使用 sapply 并且找到 logplus1 值。”与“我们想找到数据框中所有观察值的 logplus1 值”相比(这是我阅读矢量化代码的方式)
    • 啊,抱歉我没说清楚。矢量化代码当然更容易阅读。使用 Vectorize 函数矢量化的代码是我发现难以使用的代码。要了解它内部发生了什么,我必须回到原始函数声明,因为我并不特别适合在 Vectorize 函数所产生的临时环境中挖掘......以及函数的暴露部分使用 Vectorize 进行了调整并没有让我明白原始功能是什么。
    【解决方案2】:

    你应该可以只引用你想要的列,然后进行操作,即:

    df[,1:56] <- log(df[,1:56]+1)
    

    【讨论】:

      猜你喜欢
      • 2022-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-11
      • 2020-10-03
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多