2013-04-24 18 views
7

Dane pochodzą z innym pytaniem byłem zabawy z:data.table i stół nieoczekiwane zachowanie

dt <- data.table(user=c(rep(3, 5), rep(4, 5)), 
       country=c(rep(1,4),rep(2,6)), 
       event=1:10, key="user") 
# user country event 
#1:  3  1  1 
#2:  3  1  2 
#3:  3  1  3 
#4:  3  1  4 
#5:  3  2  5 
#6:  4  2  6 
#7:  4  2  7 
#8:  4  2  8 
#9:  4  2  9 
#10: 4  2 10 

A oto zaskakujące zachowanie:

dt[user == 3, as.data.frame(table(country))] 
# country Freq 
#1  1 4 
#2  2 1 

dt[user == 4, as.data.frame(table(country))] 
# country Freq 
#1  2 5 

dt[, as.data.frame(table(country)), by = user] 
# user country Freq 
#1: 3  1 4 
#2: 3  2 1 
#3: 4  1 5 
#    ^^^ - why is this 1 instead of 2?! 

Dzięki mnel i Victor K. Naturalna kontynuacja jest - czy nie powinna być 2, czyli czy jest to błąd? Spodziewałem

dt[, blah, by = user] 

wrócić identyczny wynik

rbind(dt[user == 3, blah], dt[user == 4, blah]) 

Czy to oczekiwanie błędne?

+2

Czy kraj w as.data.frame (tabela (kraj)) jest czynnikiem? Jeśli tak, to dlatego, że poziomy nie są takie same w obu. – mnel

+1

@mnel, podczas gdy masz rację, ponieważ wynika to z "as.data.frame", zmuszając do "factor", oczekiwane zachowanie byłoby dla wartości reprezentującej etykietę. Myślę, że jest to prawdopodobnie to samo, co w przypadku 'rbindlist': http://stackoverflow.com/questions/15933846/rbindlist-two-data-tables-where-one-has-factor-and-other-has- character-type-for/15935715 # 15935715 –

+0

@eddi, patrz aktualizacja do mojej odpowiedzi. –

Odpowiedz

5

Jako komentarz tworzy ramkę danych, w której pierwsza zmienna jest czynnikiem. Dla user == 4, jest tylko jeden poziom w czynnik, który jest przechowywany wewnętrznie jako 1.

Co chcesz to czynnika poziomy, ale co masz jest jak czynniki są przechowywane wewnętrznie (jako liczby całkowite, zaczynając od 1) . Poniżej przedstawiono oczekiwany wynik:

> dt[, lapply(as.data.frame(table(country)), as.character), by = user] 
    user country Freq 
1: 3  1 4 
2: 3  2 1 
3: 4  2 5 

Aktualizacja. Jeśli chodzi o twoje drugie pytanie: nie, myślę, że zachowanie jest prawidłowe. To samo dzieje się w zwykły R podczas łączenia dwóch czynników na różnych poziomach:

> a <- factor(3:5) 
> b <- factor(6:8) 
> a 
[1] 3 4 5 
Levels: 3 4 5 
> b 
[1] 6 7 8 
Levels: 6 7 8 
> c(a,b) 
[1] 1 2 3 1 2 3 
+1

Jako nuta zainteresowania 'dt [, lapply (as.data.frame.table (country)), as.character), by = user] 'daje błąd –

+1

Ale to prawdopodobnie nie ma nic wspólnego z' data.table': np. 'as.data.frame.table (dt $ country)' wytwarza ten sam błąd –

+0

To jest dobry punkt –

7

idiomatyczne data.table podejściem jest użycie .N

dt[ , .N, by = list(user, country)] 

To będzie znacznie szybciej i będzie to również zachowują kraj taki sam jak w oryginale.

+0

nice one, thanks – eddi

Powiązane problemy