2016-01-25 11 views
8

o to powtarzalne przykład:Problemy z kluczem wtórnym 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" 

Teraz nazywamy prostą komendę, która daje dość dziwny (dla mnie) Wynik:

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

Z filtrem val=='2', oczekiwałem, że dostanę zapisy 2 i 3, ale w rzeczywistości dostałem tylko rekord 3. Jest to oczywiście ze względu na klucz dodatkowy, ponieważ jego usunięcie przywraca oczekiwane zachowanie:

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

Zastanawiam się, czy to błąd, czy oczekiwane zachowanie. W moim przypadku było to oczywiście niepożądane: nie wiedziałem nawet o czymś takim jak klucz dodatkowy (przed zapytaniem that SO question) i spędziłem dużo czasu próbując dowiedzieć się, dlaczego tęsknię za niektórymi płytami. Dla mnie rozwiązałem ten problem, dodając instrukcję set2key(myDT, NULL), ale teraz niepokoję się, że coś podobnego może się zdarzyć w niektórych innych częściach mojego kodu i nie wiem jak to wykryć/zapobiec - nie chciałbym dodawać połączeń set2key(., NULL) po każdej innej linii ...

+1

Wygląda na to, że rzeczywiście jest to jakiś typ błędu. Wygląda na to, że jest on spowodowany zmianą wartości kolumny, której klucz drugorzędny jest ustawiony bez aktualizacji samego klucza drugorzędnego. ale zazwyczaj mylę się co do tych rzeczy. Warto opublikować [problem na GH] (https://github.com/Rdatatable/data.table/issues/new) –

+0

dzięki za wsparcie, opublikuję to wtedy. Zastanawiam się, czy mój kod można jeszcze bardziej uprościć, aby uczynić minimalny przykład. –

+0

Tak, możesz zrobić coś w stylu 'myDT <- data.table (ID = c (" A "," B "," B "), val = c (" sprawdź "," sprawdź "," a ")) ; myDT [val == "sprawdź"]; myDT [, val: = ifelse (.N> 1, '2', '1'), by = ID]; myDT [val == '2'] '. Wydaje się, że coś wiąże się ze zmianą wartości w kluczu, robiąc to przez grupę w połączeniu z 'ifelse'. Znalazłeś bardzo specyficzny scenariusz, o którym nie pomyśleli. –

Odpowiedz

0

to był rzeczywiście błąd (zgłosiłem to, ale okazało się, że zostało już zgłoszone), a zostało to naprawione w wersji pakietowej 1.9.7 - teraz wszystko działa!