2016-01-25 7 views
8

Hier ist ein reproduzierbares Beispiel:Probleme mit Sekundärschlüssel von data.table

myDT <- data.table(ID=c('A','B','B'), val=c('check','check','a')); 
myDT[val == "check"]; # <= secondary index created on calling this 
myDT[, val:=ifelse(.N>1, '2', '1'), by=ID] 

myDT 
# ID val 
# 1: A 1 
# 2: B 2 
# 3: B 2 

key(myDT) 
# NULL 
key2(myDT) 
# [1] "val" 

Nun nenne ich einen einfachen Befehl, der etwas seltsam (für mich) Ergebnis liefert:

myDT[val=='2', res:='yes'][]; 
# ID val res 
# 1: A 1 NA 
# 2: B 2 yes 
# 3: B 2 NA 

mit Filter val=='2', ich erwartete, Datensätze 2 und 3 zu bekommen, aber tatsächlich bekam ich nur Datensatz 3. Dies ist offensichtlich wegen des Sekundärschlüssels, weil seine Entfernung das erwartete Verhalten zurückbringt:

set2key(myDT, NULL) 
myDT[val=='2', res:='yes'][]; 
# ID val res 
# 1: A 1 NA 
# 2: B 2 yes 
# 3: B 2 yes 

Ich frage mich, ob es ein Fehler oder erwartetes Verhalten ist. In meinem Fall war es offensichtlich nicht erwünscht: Ich wusste nicht einmal etwas über Sekundärschlüssel (bevor ich fragte that SO question), und ich verbrachte viel Zeit damit herauszufinden, warum ich einige Aufzeichnungen vermisse. Für mich löste ich das Problem, indem ich set2key(myDT, NULL) Anweisung hinzufüge, aber jetzt mache ich mir Sorgen, dass ähnliche Dinge in einigen anderen Teilen meines Codes passieren können und ich nicht weiß, wie man es erkennt/verhindert - ich möchte keine set2key(., NULL) Aufrufe hinzufügen nach jeder anderen Zeile ...

+1

Es scheint in der Tat wie eine Art von Fehler. Es scheint, dass dies verursacht wird, indem die Werte der Spalte geändert werden, auf die der Sekundärschlüssel gesetzt ist, ohne den Sekundärschlüssel selbst zu aktualisieren. aber ich bin normalerweise falsch in Bezug auf diese Dinge. Es lohnt sich, eine [Ausgabe auf GH] (https://github.com/Rdatatable/data.table/issues/new) –

+0

Danke für die Unterstützung, werde ich es dann posten. Ich frage mich, ob mein Code noch weiter vereinfacht werden kann, um ein minimales Beispiel zu geben. –

+0

Ja, Sie können etwas wie 'myDT <- data.table (ID = c ('A', 'B', 'B'), val = c ('check', 'check', 'a')) ; myDT [val == "überprüfen"]; myDT [, val: = ifelse (.N> 1, '2', '1'), durch = ID]; myDT [val == '2'] '. Es scheint, als ob etwas mit dem Ändern der Werte in dem Schlüssel zusammenhängt, während es durch die Gruppe in Kombination mit "ifelse" geschieht. Sie haben ein sehr spezifisches Szenario gefunden, an das sie nicht gedacht haben. –

Antwort

0

das war in der Tat ein Fehler (ich meldete es, aber es stellte sich heraus, dass bereits gemeldet), und es wurde in Paketversion 1.9.7 behoben - jetzt funktioniert alles!