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.

È stato utile?

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
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top