Question

J'ai une structure de données qui ressemble à la suivante :

 groupA1    groupA2    groupB1    groupB2    date        text
     0         1          1          1      2013-01-01   the dog

Pour chaque groupB variable, je souhaite lister une ligne pour chaque colonne qui a une valeur de 1.Je dois lister toutes les combinaisons de groupA et groupB où les 1 sont présents dans une ligne, mais ajoutez également la date et le texte à chacune de ces combinaisons sous forme de colonnes dans cette ligne.

Les données transformées apparaîtront comme :

var_groupB  var_groupA  date         text
 groupB1    groupA2     2013-01-01    the dog
 groupB2    groupA2     2013-01-01    the dog

J'ai essayé des combinaisons de melt et ddply mais je me retrouve toujours sans l'une des variables dont j'ai besoin.

Une chose que j'ai essayée était melt(x, id.vars=c("text", "date")) mais ensuite je perds toutes les informations sur les relations entre groupA et groupB.

Je pouvais accomplir cela en utilisant une boucle désordonnée, mais je ne savais pas si un reshape il existe un utilitaire que je ne connais pas et qui pourrait faire le travail.

Était-ce utile?

La solution

Vous pourriez melt deux fois, une fois pour chaque groupe :

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")

Cela vous donnerait une ligne pour chaque combinaison de A et 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

Ensuite, vous pouvez sous-ensembler ceci et supprimer les colonnes de valeurs :

y <- y[y$val_groupA == 1 & y$val_groupB==1, ]
y <- y[, c("var_groupA", "var_groupB", "date", "text")]

Ce qui te donne ce que tu veux :

  var_groupA var_groupB       date    text
2    groupA2    groupB1 2013-01-01 the dog
4    groupA2    groupB2 2013-01-01 the dog

Bien sûr, si votre ensemble de données est plus complexe que dans votre exemple, vous pouvez rendre cette solution plus élégante en effectuant la fusion et le sous-ensemble de manière plus automatisée (par exemple, en détectant les colonnes du groupe et en les remplissant). measure.vars, variable.name, et value.name automatiquement, peut-être pour n'importe quel nombre de groupes.

Autres conseils

Les 2 premières instructions remplacent chaque 0 dans les 4 premières colonnes par "" et chaque 1 par le nom de la colonne donnant dd2.Les deux instructions suivantes génèrent toutes les combinaisons de groupA et groupB pour chaque ligne en utilisant expand.grid avec le résultat étant dd3.Enfin subset qu'à ces rangées sans "" entrées :

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 != "")

Cela donne:

     groupA  groupB     x.date  x.text
1.2 groupA2 groupB1 2013-01-01 the dog
1.4 groupA2 groupB2 2013-01-01 the dog
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top