2016-10-27 3 views
0

ein data.table wie Gegeben:Unerwartete .GRP Sequenz in data.table

library(data.table) 
n = 5000 
set.seed(123) 
pop = data.table(id=1:n, age=sample(18:80, n, replace=TRUE)) 

und eine Funktion, die einen numerischen Vektor in eine geordnete Faktor wandelt, wie zum Beispiel:

toAgeGroups <- function(x){ 
    groups=c('Under 40','40-64','65+') 
    grp = findInterval(x, c(40,65)) +1 
    factor(groups[grp], levels=groups, ordered=TRUE) 
} 

Ich sehe unerwartete Ergebnisse beim Gruppieren der Ausgabe dieser Funktion als Schlüssel und Indizieren mit .GRP.

pop[, .(age_segment_id = .GRP, pop_count=.N), keyby=.(age_segment = toAgeGroups(age))] 

kehrt:

age_segment age_segment_id pop_count 
1: Under 40    1  1743 
2:  40-64    3  2015 
3:   65+    2  1242 

Ich habe die age_segment_id Werte zu erwarten wäre c(1,2,3), nicht c(1,3,2), aber .GRP scheint sich auf der Reihenfolge des Auftretens in den zugrunde liegenden Daten zu sein (wie in by= Reihenfolge) statt sortiert Bestellung (wie in keyby=).

Ich plante auf .GRP als Index für einige zusätzliche Kennzeichnung verwenden, sondern brauche ich, wie etwas zu tun:

pop[, .(pop_count=.N), keyby=.(age_segment = toAgeGroups(age))][, age_segment_id := .I][] 

zu bekommen, was ich will.

Ist das erwartete Verhalten? Wenn ja, gibt es eine bessere Problemumgehung?

(v. 1.9.6)

+0

Ihre 'toAgeGroups' Funktion durch die' base' Funktion subsumiert ' Schnitt ', nein? – MichaelChirico

Antwort

3

Dieses Problem sollte nicht mehr 1.9.8+ von data.table in Versionen auftreten.

library(data.table) #1.9.8+ 
pop[, .(age_segment_id = .GRP, pop_count=.N), 
    keyby=.(age_segment = toAgeGroups(age))] 
# age_segment age_segment_id pop_count 
# 1: Under 40    1  1743 
# 2:  40-64    2  2015 
# 3:   65+    3  1242 

Für einige mehr finden Sie in der Diskussion here. Wie by intern arbeitet, gibt Sortiert sortierte Zeilen für jede Gruppe grundsätzlich zurück und sortiert dann die Tabelle wieder in seiner ursprünglichen Reihenfolge.

Die Änderung hat erkannt, dass diese erneute Sortierung unnötig ist, wenn keyby angegeben ist, also funktioniert Ihr Ansatz wie erwartet.

Vor (durch 1.9.6), keyby würde die Antwort am Ende gerade neu sortieren setkey, indem Sie, wie in ?data.table dokumentiert:

amen als by [keyby die s ist], aber mit zusätzlich setkey() laufen auf den by Spalten des Ergebnisses.

So auf weniger als brandneue Versionen von data.table, müssten Sie Ihren Code zu beheben, wie:

pop[(order(age), .(age_segment_id = .GRP, pop_count=.N), 
    keyby=.(age_segment = toAgeGroups(age))] 
+0

@MattDowle Ich denke, das bedeutet, die Dokumentation sollte gebastelt werden? – MichaelChirico

+0

Pinging @Arun ebenso. – MichaelChirico

Verwandte Themen