2010-07-17 10 views
7

Ziemlich grundlegende Leistungsfrage von einem R-Neuling. Ich möchte jeder Zeile in einem Datenrahmen durch eindeutige Kombinationen von Feldern eine Gruppen-ID zuweisen. Hier ist meine aktuelle Ansatz:Zuweisen von Gruppen-ID mit ddply

> # An example data frame 
> df <- data.frame(name=c("Anne", "Bob", "Chris", "Dan", "Erin"), 
        st.num=c("101", "102", "105", "102", "150"), 
        st.name=c("Main", "Elm", "Park", "Elm", "Main")) 
> df 
    name st.num st.name 
1 Anne 101 Main 
2 Bob 102  Elm 
3 Chris 105 Park 
4 Dan 102  Elm 
5 Erin 150 Main 
> 
> # A function to generate a random string 
> getString <- function(size=10) return(paste(sample(c(0:9, LETTERS, letters), size, replace=TRUE), collapse='')) 
> 
> # Assign a random string for each unique street number + street name combination 
> df <- ddply(df, 
       c("st.num", "st.name"), 
       function(x) transform(x, household=getString())) 
> df 
    name st.num st.name household 
1 Anne 101 Main 1EZWm4BQel 
2 Bob 102  Elm xNaeuo50NS 
3 Dan 102  Elm xNaeuo50NS 
4 Chris 105 Park Ju1NZfWlva 
5 Erin 150 Main G2gKAMZ1cU 

Während dies gut für Datenrahmen arbeitet mit relativ wenigen Zeilen oder einer kleinen Anzahl von Gruppen, ich laufe in Performance-Probleme mit größeren Datensätzen (> 100.000 Zeilen), die in vielen verschiedenen Gruppen haben.

Irgendwelche Vorschläge, um die Geschwindigkeit dieser Aufgabe zu verbessern? Möglicherweise mit plyrs experimentellem idata.frame()? Oder mache ich das alles falsch?

Vielen Dank im Voraus für Ihre Hilfe.

Antwort

14

Versuchen Sie, die id Funktion (auch in plyr) mit:

df$id <- id(df[c("st.num", "st.name")], drop = TRUE) 

Update:

Die id Funktion seit dplyr Version als veraltet angesehen wird 0.5.0. Die Funktion group_indices bietet die gleiche Funktionalität.

+0

Offenbar muss ich zurückgehen und die Dokumentation von plyr genauer lesen - das ist genau das, was ich gesucht habe. Ich habe diese Lösung und JoFrhwlds auf meinem Testdatensatz ausgewertet: Ein Datenrahmen mit 164.961 Beobachtungen und 91.876 eindeutigen Gruppen basierend auf 3 Gruppierungsvariablen. Ich verwendete jede dieser Methoden, um eine Gruppen-ID-Variable 100 Mal zuzuweisen. Die mittlere verstrichene Zeit für ID() war 0,958 (SD .0310). Die durchschnittliche Zeit für das Einfügen der Gruppierungsfelder betrug 1,94 (SD 0,0946). Danke an beide! – danpelota

2

Ist es notwendig, dass die ID eine zufällige 10-stellige Zeichenfolge ist? Wenn nicht, warum fügen Sie einfach die Spalten des Datenrahmens zusammen. Wenn die IDs die gleiche Länge in Zeichen lang sein, Faktoren in numerische konvertieren, dann fügen Sie sie zusammen:

df$ID <- paste(as.numeric(df$st.num), as.numeric(df$st.name), sep = "") 

Dann, wenn Sie wirklich 10 Zeichen-IDs haben müssen, ich habe gerade die Anzahl von n-IDs erzeugen würde und

df$ID <- as.factor(df$ID) 
n <- nlevels(df$ID) 

getID <- function(n, size=10){ 
    out <- {} 
    for(i in 1:n){ 
    out <- c(paste(sample(c(0:9, LETTERS, letters), size, replace=TRUE), collapse='')) 
    } 
    return(out) 
} 

newLevels <- getID(n = n) 

levels(df$ID) <- newLevels 

auch mit ihnen die Ebenen der ID umbenennen, so nebenbei, nicht wahr function(x) mit ddply diese Weise mit transform() verwenden müssen. Dieser Code würde funktionieren genauso:

ddply(df, c("st.num", "st.name"), transform, household=getString())