Ist diese Umgestaltung der Daten möglich?
Frage
Ich habe eine Datenstruktur, die wie folgt aussieht:
groupA1 groupA2 groupB1 groupB2 date text
0 1 1 1 2013-01-01 the dog
Für jede groupB
Variable möchte ich eine Zeile für jede Spalte auflisten, die den Wert 1 hat.Ich muss alle Kombinationen auflisten groupA
Und groupB
wobei Einsen in einer Zeile vorhanden sind, fügen Sie dann aber auch das Datum und den Text zu jeder dieser Kombinationen als Spalten in dieser Zeile hinzu.
Transformierte Daten würden wie folgt aussehen:
var_groupB var_groupA date text
groupB1 groupA2 2013-01-01 the dog
groupB2 groupA2 2013-01-01 the dog
Ich habe Kombinationen ausprobiert melt
Und ddply
aber ich bleibe immer ohne eine der Variablen, die ich brauche.
Eine Sache, die ich versucht habe, war melt(x, id.vars=c("text", "date"))
aber dann verliere ich alle Informationen über die Beziehungen zwischen ihnen groupA
Und groupB
.
Ich könnte dies mit einer chaotischen Schleife erreichen, war mir aber nicht sicher, ob a reshape
Es gibt ein Dienstprogramm, von dem ich nichts weiß und das die Aufgabe erfüllen könnte.
Lösung
Sie könnten melt
zweimal, einmal für jede Gruppe:
y <- melt(x, measure.vars=c("groupA1", "groupA2"),
variable.name="var_groupA", value.name="val_groupA")
y <- melt(y, measure.vars=c("groupB1", "groupB2"),
variable.name="var_groupB", value.name="val_groupB")
Das würde Ihnen eine Zeile für jede Kombination aus A und B geben:
date text var_groupA val_groupA var_groupB val_groupB
1 2013-01-01 the dog groupA1 0 groupB1 1
2 2013-01-01 the dog groupA2 1 groupB1 1
3 2013-01-01 the dog groupA1 0 groupB2 1
4 2013-01-01 the dog groupA2 1 groupB2 1
Dann könnten Sie dies unterteilen und die Wertespalten entfernen:
y <- y[y$val_groupA == 1 & y$val_groupB==1, ]
y <- y[, c("var_groupA", "var_groupB", "date", "text")]
Das gibt Ihnen, was Sie wollen:
var_groupA var_groupB date text
2 groupA2 groupB1 2013-01-01 the dog
4 groupA2 groupB2 2013-01-01 the dog
Wenn Ihr Datensatz komplexer ist als in Ihrem Beispiel, können Sie diese Lösung natürlich eleganter gestalten, indem Sie das Zusammenführen und Unterteilen auf automatisiertere Weise durchführen – z. B. durch Erkennen der Gruppenspalten und Ausfüllen measure.vars
, variable.name
, Und value.name
automatisch, vielleicht für beliebig viele Gruppen.
Andere Tipps
Die ersten 2 Anweisungen ersetzen jede 0 in den ersten 4 Spalten durch „“ und jede 1 durch den angegebenen Spaltennamen dd2
.Die nächsten beiden Anweisungen generieren alle Kombinationen von groupA
Und groupB
für jede Zeile mit expand.grid
mit dem Ergebnis dd3
.Endlich subset
das zu den Zeilen mit Nr ""
Einträge:
newvals <- function(nm) ifelse(dd[[nm]] == 0, "", nm)
dd2 <- replace(dd, 1:4, lapply(names(dd)[1:4], newvals))
combo <- function(x) data.frame(expand.grid(groupA=c(x[1:2]), groupB=c(x[3:4])),
x$date, x$text)
dd3 <- do.call("rbind", by(dd2, 1:nrow(dd2), combo))
subset(dd3, groupA != "" & groupB != "")
Das gibt:
groupA groupB x.date x.text
1.2 groupA2 groupB1 2013-01-01 the dog
1.4 groupA2 groupB2 2013-01-01 the dog