2013-04-24 19 views
7

Die Daten aus einer anderen Frage kommen ich das Spiel mit:data.table und Tabelle unerwartetes Verhalten

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 

Und hier ist das überraschende Verhalten:

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?! 

Dank MNEL und Victor K. Die natürliche Follow-up ist - sollte es nicht 2 sein, dh ist das ein Fehler? Ich erwartete

dt[, blah, by = user] 

identisches Ergebnis zu

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

Ist diese Erwartung falsch zurück?

+2

Ist Land in as.data.frame (Tabelle (Land)) ein Faktor? Wenn das so ist, dann deshalb, weil die Ebenen in beiden nicht gleich sind. – mnel

+1

@ mnel, während Sie richtig sind, dass es 'as.data.frame' ist, das auf' Faktor' gezwungen wird, wäre das erwartete Verhalten, dass der Wert das Label darstellt. Ich denke, das ist wahrscheinlich dasselbe wie bei 'rbindlist': http://stackoverflow.com/questions/15933846/rindlist-two-data-tables-where-one-has-factor-and-other-has- zeichen-type-for/15935715 # 15935715 –

+0

@eddi, siehe Update zu meiner Antwort. –

Antwort

5

Wie mnel in den Kommentaren notiert, erzeugt as.data.frame(table(...)) einen Datenrahmen, wobei die erste Variable ein Faktor ist. Für user == 4 gibt es nur eine Ebene in dem Faktor, der als 1.

intern gespeichert ist, was Sie wollen, ist Faktor Ebene, aber was man bekommt, ist, wie sie Faktoren werden intern gespeichert (als ganze Zahlen, ausgehend von 1) . Im Folgenden wird das erwartete Ergebnis:

> 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 

aktualisieren. In Bezug auf Ihre zweite Frage: Nein, ich denke data.table Verhalten ist richtig. Dasselbe geschieht in Ebene R, wenn Sie zwei Faktoren, die mit verschiedenen Ebenen verbinden:

> 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

Als eine Notiz von Interesse' dt [, lapply (as.data.frame.table (country), as.character), by = user] 'gibt einen Fehler –

+1

Das hat aber wahrscheinlich nichts mit' data.table' zu ​​tun: zB 'as.data.frame.table (dt $ country)' erzeugt den gleichen Fehler –

+0

Das ist ein guter Punkt –

7

Der idiomatische data.table Ansatz ist .N

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

Dies wird zu verwenden, viel schneller und es wird auch behalten Land als die gleiche Klasse wie im Original.

+0

nice one, thanks – eddi