Pergunta

Eu tenho uma estrutura de dados que tem o seguinte aspecto:

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

Para cada groupB variável, quero listar uma linha para cada coluna que tem um valor de 1.Eu preciso listar todas as combinações de groupA e groupB onde 1s estão presentes em uma linha, mas, em seguida, adicionar a data e texto para cada uma dessas combinações de colunas na linha.

Dados transformados apareceria como:

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

Eu tentei combinações de melt e ddply mas estou sempre deixou sem uma das variáveis que eu preciso.

Uma coisa que eu tentei foi melt(x, id.vars=c("text", "date")) mas então eu perder todas as informações sobre as relações entre groupA e groupB.

Eu poderia fazer isso usando um bagunçado loop, mas não tinha a certeza se um reshape utilitário existe que eu desconheço e poderia fazer o trabalho.

Foi útil?

Solução

Você poderia melt duas vezes, uma para cada grupo:

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

Que dê a você uma linha para cada combinação de 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

Em seguida, você pode subconjunto esta e remover as colunas de valor:

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

O que dá a você o que você deseja:

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

É claro que, se o conjunto de dados é mais complexa do que no seu exemplo, você pode fazer a esta solução mais elegante, fazendo a fusão e a subdivisão de uma forma mais automatizada moda, por exemplo, detectar o grupo de colunas e o preenchimento measure.vars, variable.name, e value.name automaticamente, talvez, para qualquer número de grupos.

Outras dicas

As 2 primeiras declarações substituir cada 0 no primeiro 4 colunas com "" e cada 1 com o nome da coluna dando dd2.As próximas duas declarações de gerar todas as combinações de groupA e groupB para cada linha usando expand.grid com o resultado sendo dd3.Finalmente subset que essas linhas sem "" entradas:

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

Isso 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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top