2016-05-16 8 views
2

Ich habe einen großen Datenrahmen mit Gruppen und Untergruppen. Ich mag den Index der Untergruppe in jeder Gruppe bestimmen, wie in der OUTPUT Spalte des folgenden Datenrahmen gezeigt:Untergruppe Index bestimmen

df <- data.frame(
    Group = factor(c("A","A","A","A","A","B","B","B","B")), 
    Subgroup = factor(c("a","a","b","b","b","a","a","b","b")), 
    OUTPUT = c(1,1,2,2,2,1,1,2,2) 
) 

ich mehrere Möglichkeiten ohne Erfolg versucht habe. Ich würde gern mit dplyr arbeiten, aber ich bin mir nicht sicher, wie ich das anstellen soll. Der folgende Code gibt ein unerwartetes Ergebnis zurück.

require(dplyr) 

df <- df %>% 
    group_by(Group) %>% 
    mutate(
    OUTPUT_2 = dplyr::id(Subgroup) 
) 

#df 
# Group Subgroup OUTPUT_2 
# (fctr) (fctr) (int) 
#1  A  a  8 
#2  A  a  8 
#3  A  b  8 
#4  A  b  8 
#5  A  b  8 
#6  B  a  4 
#7  B  a  4 
#8  B  b  4 
#9  B  b  4 

Ich habe das Gefühl, ich bin in der Nähe, aber nicht dort hin. Kann jemand helfen?

+1

von 'Gruppe' Gruppierung Sie benötigen etwas wie ' as.numerisch (Untergruppe) '? – aosmith

Antwort

2

Wir verwenden die factor Route mit dplyr

library(dplyr) 
df %>% 
    group_by(Group) %>% 
    mutate(OUTPUT = as.numeric(factor(Subgroup, levels= unique(Subgroup)))) 
# Group Subgroup OUTPUT 
# <fctr> <fctr> <dbl> 
#1  A  a  1 
#2  A  a  1 
#3  A  b  2 
#4  A  b  2 
#5  A  b  2 
#6  B  a  1 
#7  B  a  1 
#8  B  b  2 
#9  B  b  2 

Oder eine andere Option ist match mit den unique Elemente 'Untergruppe' nach

df %>% 
    group_by(Group) %>% 
    mutate(OUTPUT = match(Subgroup, unique(Subgroup))) 
# Group Subgroup OUTPUT 
# <fctr> <fctr> <int> 
#1  A  a  1 
#2  A  a  1 
#3  A  b  2 
#4  A  b  2 
#5  A  b  2 
#6  B  a  1 
#7  B  a  1 
#8  B  b  2 
#9  B  b  2 
+1

sehr nett, vielen Dank! Du wirst akzeptiert, da es einfach ist und dplyr beinhaltet, wie ich es mir erhofft hatte :-) – Ratnanil

1
library(data.table) 
dt = as.data.table(df) # or setDT to convert in place 

unique(dt[, .(Group, Subgroup)])[, idx := 1:.N, by = Group][dt, on = c('Group', 'Subgroup')] 
# Group Subgroup idx OUTPUT 
#1:  A  a 1  1 
#2:  A  a 1  1 
#3:  A  b 2  2 
#4:  A  b 2  2 
#5:  A  b 2  2 
#6:  B  a 1  1 
#7:  B  a 1  1 
#8:  B  b 2  2 
#9:  B  b 2  2 

Die Übersetzung in dplyr sollte einfach sein.


Eine andere Methode, nach der Idee von Faktoren ab AOSMITH Kommentar verwenden, ist:

dt[, idx := as.integer(factor(Subgroup, unique(Subgroup))), by = Group][] 

Dies wird ein Faktor mit der richtigen Ebenen pro Gruppe erstellen, die ist die Indizierung Sie nach.

2

Hier ist eine Lösung mit data.table ohne Aggregation:

dt[order(Subgroup), Output := cumsum(!duplicated(Subgroup)) , by = .(Group)] 

Dies wird schneller viel im Vergleich zu Methoden, die auf die Aggregation basiert.

+0

Dies funktioniert nicht, wenn Untergruppenelemente gemischt werden - z. Ändern Sie 'dt [6, Untergruppe: = 'b']' auf OP-Daten und versuchen Sie es erneut – eddi

+0

@eddi das ist wahr, aber es ist leicht lösbar mit 'setkey' – Bulat

+2

Bulat, das ist wahr, aber noch besser wäre zu haben ' Ordnung (Untergruppe) 'in dem 'i' Argument, das die ursprüngliche Reihenfolge von 'dt' * und * nicht stören würde, ist sehr effizient, da es die Umordnung vermeidet (was teuer ist). – Arun

Verwandte Themen