R中data.table中的逻辑索引

时间:2016-06-03 09:02:51

标签: r data.table logical-operators

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

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

2 个答案:

答案 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中它会自动发生