2013-07-02 16 views
33

Ich möchte die Anzahl der eindeutigen Werte durch Gruppierung einer zweiten Variablen zählen und dann die Zählung zum vorhandenen data.frame als neue Spalte hinzufügen. Zum Beispiel sieht, wenn die vorhandene Datenrahmen wie folgt aus:Anzahl der eindeutigen Werte nach Gruppe zu R hinzufügen data.frame

color type 
1 black chair 
2 black chair 
3 black sofa 
4 green sofa 
5 green sofa 
6 red sofa 
7 red plate 
8 blue sofa 
9 blue plate 
10 blue chair 

ich für jede color hinzufügen möchten, die Anzahl der eindeutigen types, die in der Daten vorhanden sind:

color type unique_types 
1 black chair   2 
2 black chair   2 
3 black sofa   2 
4 green sofa   1 
5 green sofa   1 
6 red sofa   2 
7 red plate   2 
8 blue sofa   3 
9 blue plate   3 
10 blue chair   3 

Ich hatte gehofft, zu Verwenden Sie ave, aber kann nicht scheinen, eine einfache Methode zu finden, die nicht viele Zeilen erfordert. Ich habe> 100.000 Zeilen, also bin ich mir auch nicht sicher, wie wichtig Effizienz ist.

Es ist etwas ähnlich dieser Ausgabe: Count number of observations/rows per group and add result to data frame

Antwort

39

Mit ave (da Sie danach fragen speziell):

within(df, { count <- ave(type, color, FUN=function(x) length(unique(x)))}) 

Stellen Sie sicher, dass type Zeichen Vektor und nicht Faktor.


Da Sie auch Ihre Daten sind riesig sagen und dass die Geschwindigkeit/Leistung daher ein Faktor sein kann, würde ich eine data.table Lösung als auch vorschlagen.

require(data.table) 
setDT(df)[, count := uniqueN(type), by = color] # v1.9.6+ 
# if you don't want df to be modified by reference 
ans = as.data.table(df)[, count := uniqueN(type), by = color] 

uniqueN wurde in v1.9.6 implementiert und ist ein schneller Äquivalent length(unique(.)). Außerdem funktioniert es auch mit data.frames/data.tables.


Andere Lösungen:

Mit plyr:

require(plyr) 
ddply(df, .(color), mutate, count = length(unique(type))) 

aggregate Verwendung:

agg <- aggregate(data=df, type ~ color, function(x) length(unique(x))) 
merge(df, agg, by="color", all=TRUE) 
30

Hier ist eine Lösung mit dem dplyr Paket - es n_distinct() als Wrapper hat für length(unique()) .

df %>% 
    group_by(color) %>% 
    mutate(unique_types = n_distinct(type)) 
4

Dies kann auch ohne unique

Wenn df$color mit table oder tabulate durch die Kombination von Gruppen-Operationen in einem vektorisierten erreicht werden soll factor, dann

Entweder

table(unique(df)$color)[as.character(df$color)] 
# black black black green green red red blue blue blue 
# 2  2  2  1  1  2  2  3  3  3 

Oder

tabulate(unique(df)$color)[as.integer(df$color)] 
# [1] 2 2 2 1 1 2 2 3 3 3 

Wenn df$colorcharacter ist dann nur

table(unique(df)$color)[df$color] 

Wenn df$color ist ein integer dann nur

tabulate(unique(df)$color)[df$color] 
Verwandte Themen