我是data.table的初学者,我正在尝试做一个非常简单的操作,在基础数据帧中看起来像这样:
percentages[percentages<0] = abs(percentages[percentages<0])
数据如下所示:
percentages
p1 p2 p3
1: 0.689 0.206 0.106
到目前为止,我发现的data.table解决方案只是获取数据:
percentages[,which(percentages<0),with=FALSE]
但它比数据帧更复杂......应该有更好的东西,但我什么都得不到......有什么建议吗?
答案 0 :(得分:2)
一般选项可能是使用set
。它包含一个for
循环,但它会更有效率,因为我们循环遍历列而不是通过执行matrix
来创建df1 < 0
- 对于大型数据集,这将消耗一些内存) 。使用set
将非常有效,因为文档说明避免了[.data.table
的开销
for(j in seq_along(df1)){
set(df1, i = which(df1[[j]]<0), j=j, value = abs(df1[[j]]))
}
由于OP想要单行代码,对于单行示例显示,
df1[, lapply(.SD, function(x) replace(x, x < 0, abs(x)))]
基于稍大一点的数据集上的system.time
set.seed(42)
dfN <- data.frame(p1 = rnorm(1e7), p2 = rnorm(1e7), p3 = rnorm(1e7), p4 = rnorm(1e7))
dfN1 <- copy(dfN)
setDT(dfN1)
system.time({
i1 <- dfN < 0
dfN[i1] <- abs(dfN[i1])
})
# user system elapsed
# 1.63 0.50 2.12
system.time({
for(j in seq_along(dfN1)){
set(dfN1, i = which(dfN1[[j]]<0), j=j, value = abs(dfN1[[j]][dfN1[[j]]<0]))
}
})
# user system elapsed
# 0.91 0.08 0.98
答案 1 :(得分:-1)
如上所述akrun,单行回复是
df1[, lapply(.SD, function(x) replace(x, x < 0, abs(x)))]
但是,这并不是我想要的,因为与data.frame相比,data.table似乎在语法上更复杂(至少在这个例子中)
我们基本上在data.table(使用lapply)中进行矢量化,而在data.frame中它会自动发生