2013-01-16 56 views
4

我想問一下爲什麼在我改變的時候,下面例子中的data.table失去了它的key某個where子集的關鍵變量的值。是否有必要。在一個keyed data.table中,將某個`where`的key變量的值設置爲`NULL`

library(data.table) 
example(data.table) 
setkey(DT,x) # one key var only 
DT[J("a"), x := "z"] 
DT 
    x y v v2 m 
1: z 1 13 84 5 
2: z 3 13 84 5 
3: z 6 13 84 5 
4: c 1 7 NA 8 
5: c 3 8 NA 8 
6: c 6 9 NA 8 
7: z 1 42 NA 42 
8: z 3 42 NA 42 
9: z 6 42 NA 42 

使作品就好了。不過,我失去了我的鑰匙:

key(DT) 
NULL 

我想通過重新分配鍵上方的鍵列x被刪除。也許鑰匙應該被記住,即應該有一個隱含的setkey(DT,x)來保持x作爲鑰匙?謝謝!

我正在使用版本1.8.6。順便一提。

+1

FWIW,你不需要'Ĵ( 'A')','DT [ '一',X:= 'Z' ]'也會這樣做。但也許這是一個很好的功能添加。像'levels'因素可能會有'updatekey'功能... – Justin

回答

4

setkey的幫助文件:

'的setkey()排序一個‘data.table’和分類標誌着它。 [...]總是按升序排列 列。

當您更換在任何鍵列的要素時,data.table不再訂購(或者至少不能保證是),所以關鍵是沒有設置以反映變化的現實。

一個簡單的解決方法就是立即復位鍵:

## Creates the example data.table 
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9) 
setkey(DT, 'x') 

## Immediately resets the (possibly multicolumn) key 
setkeyv(DT["a", x:="z"], key(DT)) 

key(DT) 
# [1] "x" 
+0

是的,我做了這樣的事情 - 聽起來像是一個合理的解決方案給我。只是想看看你們的想法。乾杯! –

+0

嗯,我意識到這可能是一個愚蠢的問題 - 我沒有想過完全沒有完成的訂購。謝謝澄清! –

+0

+1 @FlorianOswald我們考慮過維護排序順序,但是會增加開銷以檢查新值是否更改了順序(如您的示例中所示)。如果它自動執行,那麼某個人肯定會將其放在更新循環中,並想知道爲什麼它會在每次迭代時重新排序!所以':='確實可以做到最快最安全的事情,但重置密鑰時由您決定。很奇怪我需要更新關鍵值。不過,可能會有一個新的參數'maintain.key'。嗯。這不是一個壞主意...... –

相關問題