R 中 data.table 中的逻辑索引

logical indexing in data.table in R

我是 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]

但它比 dataframe 更复杂...应该有更好的东西,但我什么也得不到...有什么建议吗?

一般选项可能正在使用 set。它包括一个 for 循环,但它会更有效,因为我们在列中循环而不是通过执行创建 matrixdf1 < 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 

正如阿克伦在上面发布的那样,单行回复是

df1[, lapply(.SD, function(x) replace(x, x < 0, abs(x)))]

然而,这并不是我想要的,因为 data.table 在语法上似乎比 data.frame 复杂得多(至少在这个例子中是这样)

我们基本上是在 data.table 中自己进行矢量化(使用 lapply),而在 data.frame 中它自动发生