Domanda
Ho una struttura dati che assomiglia come segue:
groupA1 groupA2 groupB1 groupB2 date text
0 1 1 1 2013-01-01 the dog
.
Per ogni variabile groupB
, voglio elencare una riga per ogni colonna che ha un valore di 1.
Ho bisogno di elencare tutte le combinazioni di groupA
e groupB
dove sono presenti 1s in una riga, ma anche aggiungere la data e il testo a ciascuna di queste combinazioni come colonne in quella riga.
I dati trasformati appariranno come:
var_groupB var_groupA date text
groupB1 groupA2 2013-01-01 the dog
groupB2 groupA2 2013-01-01 the dog
.
Ho provato combinazioni di melt
e ddply
ma sono sempre lasciato senza una delle variabili di cui ho bisogno.
Una cosa che ho provato è stato melt(x, id.vars=c("text", "date"))
ma poi perdo tutte le informazioni sulle relazioni tra groupA
e groupB
.
Potrei realizzare questo usando un ciclo disordinato, ma non era sicuro se esiste un'utilità reshape
che non sono consapevole e potrebbe fare il lavoro.
Soluzione
Potresti generarecodicitagcode due volte, una volta per ciascun gruppo:
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")
.
che ti darebbe una riga per ogni combinazione di A e B:
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
.
Quindi è possibile soddisfare questo e rimuovere le colonne del valore:
y <- y[y$val_groupA == 1 & y$val_groupB==1, ]
y <- y[, c("var_groupA", "var_groupB", "date", "text")]
.
Che ti dà ciò che vuoi:
var_groupA var_groupB date text
2 groupA2 groupB1 2013-01-01 the dog
4 groupA2 groupB2 2013-01-01 the dog
.
Certo, se il tuo set di dati è più complesso rispetto al tuo esempio, è possibile rendere questa soluzione più elegante facendo la fusione e la sottotalia in modo più automatico, ad esempio, rilevando le colonne del gruppo e il riempimento melt
, measure.vars
,e variable.name
automaticamente, forse per qualsiasi numero di gruppi.
Altri suggerimenti
Le prime 2 istruzioni sostituiscono ciascuna 0 nelle prime 4 colonne con "" e ciascuna 1 con il nome della colonna che fornisce dd2
.Le prossime due dichiarazioni generano tutte le combinazioni di groupA
e groupB
per ogni riga utilizzando expand.grid
con il risultato che è generatoDICETAGCODE.Infine dd3
che a quelle righe senza voci subset
:
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 != "")
.
Questo dà:
groupA groupB x.date x.text
1.2 groupA2 groupB1 2013-01-01 the dog
1.4 groupA2 groupB2 2013-01-01 the dog
.