data.table行搜索的奇怪问题

时间:2016-02-12 01:46:40

标签: r data.table

我是R.的忠实粉丝和大量用户。我真的将它们用于很多代码,但最近遇到了一个奇怪的错误:

我有一个包含多列的巨大data.table,例如:

   x y
1: 1 a
2: 1 b
3: 1 c
4: 2 a
5: 2 b
6: 2 c
7: 3 a
8: 3 b
9: 3 c

如果我选择

dataDT[x==‘1’]  

我最终得到了

   x y
1: 1 a

dataDT[(x==‘1’)]

给了我

   x y
1: 1 a
2: 1 b
3: 1 c

有什么想法吗? x和y是因子,data.table由setKey x索引。

其他信息和代码:

我实际上修复了这个问题,但其方式不明确也不直观。

我的代码结构如下:我有一个从我的主代码调用的函数,我必须在data.table中引入一个列。

我之前使用过以下符号

dataT [,NC:=摄氏度,]

做行动。

我发现使用

创建新列

dataT $ nC< - dataT $ oC

完全修复了这个错误。

我尝试在一个更简单的示例代码上复制完全相同的错误,但我不能,可能是因为与data.table的大小结构相关的依赖关系以及我在桌面上运行的特定函数。

话虽如此,我有一个工作示例,它表明当您使用dataT [,nC:= oC,]表示法插入列时,它就好像表是通过引用函数而不是通过值传递的。

另外,有趣的是,在执行

dataDT [x =='1']

VS

dataDT [(x =='1')]

显示相同的结果,后者慢了10倍,我之前已经注意到了。我希望这段代码可以解释一下。

rm(list=ls())
library(data.table)


superParF <- function(dtInput){

  dtInputP <- dtInput[a==1]
  dtInputN <- dtInput[a==2]

  outDT    <- rbind(dtInputP[,sum(y),by='x'],
                    dtInputN[,sum(y),by='x'])
  return(outDT)
}

superFunction <- function(dtInput){

  #create new column
  dtInput[,z:=y,]

  #run function
  outDT <- rbindlist(lapply(unique(inputDT$x),
                        function(i)
                          superParF(inputDT[x==i])))
  #output outDT
  return(outDT)
}




inputDT <- data.table(x = c(rep(1,100000),
                        rep(2,100000),
                        rep(3,100000),
                        rep(4,100000),
                        rep(5,100000)),
                  y= c(rep(1:100000,5)))

inputDT$x <-  as.factor(inputDT$x)
inputDT$y <- as.numeric(inputDT$y)

inputDT   <- rbind(inputDT,inputDT)
inputDT$a <- c(rep(1,500000),rep(2,500000))

setkey(inputDT,x)

#first observation-> the two searches do not work with the same performance

a <- system.time(inputDT[x=='1'])
b <- system.time(inputDT[(x=='1')])

print(a)
print(b)

out <- superFunction(inputDT)

a <- system.time(inputDT[x=='1'])
b <- system.time(inputDT[(x=='1')])

print(a)
print(b)

inputDT

2 个答案:

答案 0 :(得分:3)

我在评论中提出要提供版本号并遵循Support页面上的指南。它包含:

  

阅读并搜索README.md。是否存在与您的问题相关的错误修复或新功能?可能我们知道这个问题或其他人报告了这个问题,我们已经在当前的开发版本中解决了这个问题。

因此,在README.md中搜索字符串&#34; index&#34;只需在浏览器中使用Ctrl-F,就可以得到:

  

21自动索引使用数值正确处理因子列的逻辑子集,#1361。谢谢@mplatzer。   

     

26当输入data.table已经排序时,自动索引正确地返回子集的顺序,#1495。谢谢@huashan的好评   可重复的例子。

在v1.9.7中修复了这些内容,使用Installation页面上详述的一个命令轻松安装。

第一个(第21项)看起来非常接近您的问题。因此,请按照第4点的支持页面上的要求尝试v1.9.7。

我们要求您预先说明版本号以节省时间,因为我们希望确保您在CRAN上使用至少v1.9.6而不是v1.9.4,这有此问题:

  

DT [column == value]不再回收值,除了长度为1的情况(当它仍使用DT的密钥或自动二级密钥时,如v1.9.4中所介绍的)。如果length(value)== length(column)则它在R中作为标准元素工作。否则,发出长度错误以避免常见的用户错误。 DT [%%in%values]仍然像以前一样使用DT的密钥(或自动二级密钥)。仍然可以使用选项(datatable.auto.index = FALSE)关闭自动索引(即,==和%in%的优化)。

请问您正在运行哪个版本并尝试过v1.9.7,因为它看起来值得一试?

答案 1 :(得分:1)

使用dT [,Column:= Value]符号似乎也会在另一篇帖子中引起相同的错误!

data.table not recognising logical in filter

用dT $ Column&lt; - 替换dT [,Column:= Value] - 修复了我的bug和这个帖子的bug。

@Matt Dowle:我发布的这篇帖子有更简洁的代码,而且bug也是一样的!你会发现解决这个问题很有帮助!