Вопрос

У меня есть структура данных, которая выглядит следующим образом:

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

Для каждого groupB переменной, я хочу перечислить одну строку для каждого столбца со значением 1.Мне нужно перечислить все комбинации groupA и groupB где единицы присутствуют в одной строке, но затем также добавьте дату и текст к каждой из этих комбинаций в виде столбцов в этой строке.

Преобразованные данные будут выглядеть так:

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

Я пробовал комбинации melt и ddply но я всегда остаюсь без одной из нужных мне переменных.

Одна вещь, которую я попробовал, была melt(x, id.vars=c("text", "date")) но тогда я теряю всю информацию об отношениях между groupA и groupB.

Я мог бы сделать это, используя беспорядочный цикл, но не был уверен, что reshape существует утилита, о которой я не знаю, и которая могла бы выполнить эту работу.

Это было полезно?

Решение

Вы могли бы melt дважды, по одному для каждой группы:

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

Это даст вам одну строку для каждой комбинации A и 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

Затем вы можете подмножество этого и удалить столбцы значений:

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

Что дает вам то, что вы хотите:

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

Конечно, если ваш набор данных более сложен, чем в вашем примере, вы можете сделать это решение более элегантным, выполнив объединение и подмножество более автоматизированным способом - например, обнаружив групповые столбцы и заполнив их. measure.vars, variable.name, и value.name автоматически, возможно, для любого количества групп.

Другие советы

Первые два оператора заменяют каждый 0 в первых 4 столбцах на "" и каждую 1 на имя столбца, дающее dd2.Следующие два утверждения генерируют все комбинации groupA и groupB для каждой строки, используя expand.grid с результатом dd3.Окончательно 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 != "")

Это дает:

     groupA  groupB     x.date  x.text
1.2 groupA2 groupB1 2013-01-01 the dog
1.4 groupA2 groupB2 2013-01-01 the dog
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top