【发布时间】:2021-10-12 14:10:57
【问题描述】:
我有一个 58 列的数据框,我需要将转换 $log(x_{i,j}+1)$ 应用于前 56 列中的所有值。我可以使用什么方法最有效地解决这个问题?我假设有一些东西可以让我这样做,而不仅仅是使用一些 for 循环来运行整个数据帧。
【问题讨论】:
标签: r
我有一个 58 列的数据框,我需要将转换 $log(x_{i,j}+1)$ 应用于前 56 列中的所有值。我可以使用什么方法最有效地解决这个问题?我假设有一些东西可以让我这样做,而不仅仅是使用一些 for 循环来运行整个数据帧。
【问题讨论】:
标签: r
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 函数来绕过未矢量化的函数。
你应该可以只引用你想要的列,然后进行操作,即:
df[,1:56] <- log(df[,1:56]+1)
【讨论】: