不要求助data.table行

时间:2014-05-17 14:46:23

标签: r data.table

我正在学习data.table所以我对它的语法很新。我试图使用该包作为哈希查找,它工作得很好,除了,因为我不懂语法,它重新排序行。我希望它不要在不牺牲速度的情况下重新排序行(即,实现这一点的有效方法)。这是一个示例和所需的输出:

library(data.table)

(key <- setNames(aggregate(mpg~as.character(carb), mtcars, mean), c("x", "y")))
set.seed(10)
terms <- data.frame(x = c(9, 12, sample(key[, 1], 6, TRUE)), stringsAsFactors = FALSE)

## > terms$x
## [1] "9"  "12" "4"  "2"  "3"  "6"  "1"  "2"

setDT(key)
setDT(terms)
setkey(key, x) 
setkey(terms, x)
terms[key, out := i.y]
terms

这给出了:

##     x      out
## 1:  1 25.34286
## 2: 12       NA
## 3:  2 22.40000
## 4:  2 22.40000
## 5:  3 16.30000
## 6:  4 15.79000
## 7:  6 19.70000
## 8:  9       NA

我想:

##     x      out
## 1:  9       NA
## 2: 12       NA
## 3:  4 15.79000
## 4:  2 22.40000
## 5:  3 16.30000
## 6:  6 19.70000
## 7:  1 25.34286
## 8:  2 22.40000

1 个答案:

答案 0 :(得分:2)

  

data.table中,加入x[i] 来设置x的密钥,但密钥不是必需的设为i

     

注意:但如果您没有为i设置密钥,

     
      
  • 1)确保i的列与x的键列的顺序相同(如有必要,请使用setcolorder重新排序),因为它不会&# 39;通过检查姓名来加入。(

  •   
  • 2)它的速度可能稍慢(但在我的基准测试中并不多)。

  •   

因此,问题在于,如果您只想进行x[i]加入而不进行任何其他预处理,那么terms必须取代i而不按顺序设置密钥以您需要的顺序获得结果。

考虑到这一点,我们可以通过两种方式(我能想到的)来解决这个问题。


第一种方法:

这个要求没有额外的预处理。我们将key视为x如上所述 - 意味着它的关键已设置。我们没有为terms设置密钥。

setkey(key, x)

terms的第一列也被命名为x,而且我们想要加入的列。所以,这里不需要重新排序。

ans = key[terms]
> ans
#     x        y
# 1:  9       NA
# 2: 12       NA
# 3:  4 15.79000
# 4:  2 22.40000
# 5:  3 16.30000
# 6:  6 19.70000
# 7:  1 25.34286
# 8:  2 22.40000

不同之处在于,这是一个全新的data.table,而不仅仅是通过引用分配列。


第二种方法:

我们进行了一些额外的预处理 - 通过引用向N添加了一个额外的列terms,该列从1:nrow(terms)开始运行。这基本上有助于我们在连接后以所需的顺序重新排列数据。在此,我们将terms视为x

terms[, N := 1:.N]
setkey(terms, x)

key有&#39; x&#39;并不重要。列设置为键..但请再次确保xkey中的第一列,如果它的键未设置..在我的情况下,我会立即将key的键列设置为x

setkey(key, x)
setkey(terms[key, out := i.y], N)
> terms
#     x N      out
# 1:  9 1       NA
# 2: 12 2       NA
# 3:  4 3 15.79000
# 4:  2 4 22.40000
# 5:  3 5 16.30000
# 6:  6 6 19.70000
# 7:  1 7 25.34286
# 8:  2 8 22.40000

就个人而言,由于您需要terms未分类,我在此处使用第一种方法。但您可以根据您的实际数据维度进行基准测试,并选择最适合您的需求。