2015-02-02 5 views
5

ich eine Liste von Zeichenvektoren in einer Liste wie folgt gespeichert:Convert Liste der Vektoren in Datenrahmen des Grafen

basket1 <- c("Apple", "Orange", "Banana", "Apple", "Apple", "Grape") 
basket2 <- c("Grape", "Grape", "Grape", "Grape") 
basket3 <- c("Kiwi", "Apple", "Cantaloupe", "Banana") 
basket4 <- c("Strawberry") 
basket5 <- c("Grape", "Grape", "Grape") 
FruitBasketList <- list(basket1, basket2, basket3, basket4, basket5) 

Und ich würde mit einer Zählung von jedem die FruitBasketList in einen Datenrahmen drehen möge Früchte in jeder Reihe, die zu dem Korb passen, aus dem er kam. Das Hauptproblem, das ich habe, ist, dass es Tausende von verschiedenen "Früchten" in jedem Vektor geben könnte und viele von ihnen werden mehr als einmal erscheinen.

Dies wird der gewünschte Datenrahmen I als Folge möchte:

Basket Apple Orange Banana Grape Kiwi Cantaloupe Strawberry 
basket1 3  1  1  1  0  0   0 
basket2 0  0  0  4  0  0   0 
basket3 1  0  1  0  1  1   0 
basket4 0  0  0  0  0  0   1 
basket5 0  0  0  3  0  0   0 

Offensichtlich ist dies nicht meine echten Daten, aber ich dachte, ich würde vereinfachen, was die Daten wie so aussehen Jeder würde es verstehen können. Nein, das sind keine Hausaufgaben. Wie auch immer, die Anzahl der Früchte in einem Korb kann tausend verschiedene Früchte sein und die Längen jedes Fruchtvektors wären nicht gleich. Es kann auch Zehntausende von Körben (Vektoren) geben. Offensichtlich konnten einige Früchte mehrmals im selben Vektor (Korb) wiederholt werden. Ich habe daran gearbeitet, das zu lösen, aber ich bin mir sicher, dass es furchtbar kompliziert und sehr ineffizient ist. Bisher besteht meine Lösung darin, alle Vektoren von allen Vektoren zu kombinieren und dann alle eindeutigen Fruchtnamen zu identifizieren, die möglich sind. Das hat gut funktioniert. Dann erstellt der Teil, mit dem ich zu kämpfen habe, einen leeren Datenrahmen aus all diesen eindeutigen Spaltennamen, dann für jeden Vektor, der jede einzelne Frucht zählt und dann diesen Wert in die richtige Spalte in einer neuen Reihe im Datenrahmen einfügt mit Nullen für Früchte, die in diesem bestimmten Korb nicht existieren.

Der Code Ich bin mit einzelnen Vektoren Tally sieht wie folgt aus:

GetUniqueItemCount <- function(rle, value) 
{ 
    value <- rle$lengths[rle$values == value] 
    if (identical(value, integer(0))) 
    { 
    value <- 0 
    } 
    value 
} 

Und den Code nennen es wie folgt aussieht:

Apple <- GetUniqueItemCount(rle, "Apple") 

Wie Sie in meinem aktuellen sehen Code Ich muss alle möglichen Früchte vor der Hand kennen und die Zählung jeder Frucht fest codieren und sie dann einer bestimmten Spalte zuordnen, die vorher im Datenrahmen bekannt ist. Wie auch immer, ich merke, dass ich hier den falschen Weg eingeschlagen habe, daher würde ich mich über jeden Rat freuen, wenn ich wieder auf den richtigen Weg komme, um meinen oben gezeigten gewünschten Datenrahmen zu bekommen. Bitte zögern Sie nicht, einen völlig anderen Ansatz zu bieten, anstatt zu versuchen, herauszufinden, wie Sie meine Arbeit erledigen können, wenn dies der beste Weg wäre, das Problem zu lösen.

Antwort

9

tun würde ich mtabulate aus dem „qdapTools“ Paket vorschlagen.

library(qdapTools) 
mtabulate(FruitBasketList) 
# Apple Banana Cantaloupe Grape Kiwi Orange Strawberry 
# 1  3  1   0  1 0  1   0 
# 2  0  0   0  4 0  0   0 
# 3  1  1   1  0 1  0   0 
# 4  0  0   0  0 0  0   1 
# 5  0  0   0  3 0  0   0 

Die package's author teilt sogar Ihren Avatar. Flott.

+0

ich bin Ich bin froh, dass ich diese Frage gestellt habe, da sie mich zu diesem Paket und Tylers Blog geführt hat, was ich bisher als sehr faszinierend empfunden habe! Danke, dass Sie diese Lösung auf Ananda aufmerksam gemacht haben! – Beaker

5

Mit dplyr, ich könnte so etwas wie

library(dplyr) 
m <- FruitBasketList %>% lapply(table) %>% lapply(as.list) %>% 
    lapply(data.frame) %>% rbind_all() 
m 

# Source: local data frame [5 x 7] 
# 
# Apple Banana Grape Orange Cantaloupe Kiwi Strawberry 
# 1  3  1  1  1   NA NA   NA 
# 2 NA  NA  4  NA   NA NA   NA 
# 3  1  1 NA  NA   1 1   NA 
# 4 NA  NA NA  NA   NA NA   1 
# 5 NA  NA  3  NA   NA NA   NA 

tun, die fehlenden Werte als NA verlassen wird. wenn man sie auf 0 setzen möchten, können Sie

m[is.na(m)]<-0 
m 

# Source: local data frame [5 x 7] 
# 
# Apple Banana Grape Orange Cantaloupe Kiwi Strawberry 
# 1  3  1  1  1   0 0   0 
# 2  0  0  4  0   0 0   0 
# 3  1  1  0  0   1 1   0 
# 4  0  0  0  0   0 0   1 
# 5  0  0  3  0   0 0   0 
0

Sie Funktion table auf jede Zeile anwenden können, rbind dann das Ergebnis mit gtools::smartbind

1

Sie könnten die "Liste" und umformen von "long" auf "breit" mit dcast

library(reshape2) 
dcast(melt(setNames(FruitBasketList, ls(pattern='^basket'))), L1~value) 
#  L1 Apple Banana Grape Orange Cantaloupe Kiwi Strawberry 
#1 basket1  3  1  1  1   0 0   0 
#2 basket2  0  0  4  0   0 0   0 
#3 basket3  1  1  0  0   1 1   0 
#4 basket4  0  0  0  0   0 0   1 
#5 basket5  0  0  3  0   0 0   0 

melt Or mit base R Funktionen stack und table

df <- stack(setNames(FruitBasketList, ls(pattern='^basket'))) 
table(df[2:1]) 
#   values 
#ind  Apple Banana Cantaloupe Grape Kiwi Orange Strawberry 
# basket1  3  1   0  1 0  1   0 
# basket2  0  0   0  4 0  0   0 
# basket3  1  1   1  0 1  0   0 
# basket4  0  0   0  0 0  0   1 
# basket5  0  0   0  3 0  0   0