7 Stimmen

Zuweisung einer Gruppen-ID mit ddply

Ziemlich grundlegende Leistung Frage von einem R-Neuling. Ich möchte eine Gruppe ID zu jeder Zeile in einem Datenrahmen durch eindeutige Kombinationen von Feldern zuweisen. Hier ist mein aktueller Ansatz:

> # 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 für Datenrahmen mit relativ wenigen Zeilen oder einer geringen Anzahl von Gruppen gut funktioniert, stoße ich bei größeren Datensätzen (> 100.000 Zeilen), die viele eindeutige Gruppen haben, auf Leistungsprobleme.

Gibt es Vorschläge zur Verbesserung der Geschwindigkeit dieser Aufgabe? Möglicherweise mit der experimentellen idata.frame() von plyr? Oder gehe ich das alles falsch an?

Vielen Dank im Voraus für Ihre Hilfe.

14voto

hadley Punkte 97925

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

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

更新しました。

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

2voto

JoFrhwld Punkte 8637

Muss die ID eine zufällige 10-stellige Zeichenfolge sein? Wenn nicht, warum nicht einfach die Spalten des Datenrahmens zusammenfügen? Wenn die IDs die gleiche Länge in Zeichen haben müssen, konvertieren Sie die Faktoren in numerische Werte und fügen Sie sie dann zusammen:

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

Dann, wenn Sie wirklich brauchen, um 10 Zeichen IDs haben, würde ich nur die n Anzahl von IDs zu generieren, und benennen Sie die Ebenen der ID mit ihnen

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

Nebenbei bemerkt, brauchen Sie auch nicht die function(x) mit ddply auf diese Weise mit transform() . Dieser Code würde genau so funktionieren:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X