【问题标题】:logical indexing in data.table in RR中data.table中的逻辑索引
【发布时间】:2016-06-03 09:02:50
【问题描述】:

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

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

【问题讨论】:

  • 请显示几行数据集和预期输出
  • 您可能不需要which,但对于子集data.table,需要with=FALSE。此外,如果是百分比,则为 .SD
  • 好的,谢谢,刚刚尝试了您的建议,但似乎不起作用..
  • > percents$p1=-0.54 > percents[,.SD
  • 您是否像示例中那样只有一行?无论如何,df1[, df1[, .SD &lt; 0], with = FALSE] 似乎工作或df1[, sapply(df1, "&lt;", 0), with = FALSE]

标签: r data.table logical-operators


【解决方案1】:

一般选项可能是使用set。它包括一个for 循环,但它会更有效,因为我们循环遍历列而不是通过这样做创建matrixdf1 &lt; 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 

【讨论】:

  • 感谢您的解决方案,但如果在基本数据帧中它是一个矢量化操作,那么我试图避免在“data.table 世界”中添加一个 for 循环
  • @sen_saven 请阅读答案并查看?set帮助页面
  • 我再说一遍,在数据框中我会在一行中做到这一点,data.table 中是否有类似的单行解决方案是或否?...我记得有一个,但如果不是,它就是这样......
  • @sen_saven 这是一个高效的解决方案,这正是 data.table 的用途。您可以在一行中在 base R 中做几件事,例如,如果您使用 aggregate 进行分组操作,它非常紧凑,但对于大数据集可能效率不高。
  • 另一个选项是融合 data.table 因为它可能应该是长格式。或者使用 matrix 代替 data.table/data.frame。
【解决方案2】:

正如 akrun 上面发布的那样,单行回复是

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

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

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

【讨论】:

  • 我对你的答案投了反对票,因为你使用的是@akrun 的答案,显然你没有仔细阅读。
  • @rafa.pereira 显然您没有阅读我最初的问题...您可以随意投反对票,但首先阅读初始点中所写的内容并不是一个坏主意(即关于句法复杂性)
  • 我已经阅读了你的问题,我理解你的意思。但是,也许您认为这是一个复杂的语法,因为您是 data.table 的新手,正如您所提到的。我自己同意set 循环起初看起来确实很复杂。我对否决票的观点是,将别人的答案归功于他人并不是一个好习惯,在整个讨论中,你本可以在其他 cmet 中更有礼貌,你的问题可能会更清楚,最好有一个可重复的例子和预期输出 。一切顺利,拉法
  • @rafa.pereira: 1. 你指责我为别人争光是没有道理的......我确实清楚地提到了他的名字 2. 即使现在我仍然对你无关紧要的指责保持礼貌 3.这个问题是一个基本操作,它可以在 R 中使用基本包重现。 4. 你可能会错过 lapply 或 replace 不是 data.table 包的一部分,所以这不是因为我是这个包的新手,我声明语法似乎更复杂......它只是更复杂。 ..
猜你喜欢
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
  • 2018-01-19
  • 1970-01-01
  • 2016-10-30
相关资源
最近更新 更多