Как преобразовать данные в широкий формат?

#r #reshape

#r #изменить

Вопрос:

У меня есть такой набор данных:

 structure(list(var1 = c("APE", "APE", "APE", "APE", "APE", "APE", "GIT",
"APE", "APE", "APE", "APE", "APE", "APE", "APE", "GIT"), var2 = c("AVVAL",
"AULASU", "APALA", "AEA", "ATUPVA", "ASATAP", "ADLO", "AKOKU", "AVVAL",
"AULASU", "APALA", "AEA", "ATUPVA", "ASATAP", "ADLO"), var3 = c(NA,
NA, 1L, 101L, 17122009L, 1L, NA, 684L, NA, NA, 1L, 10L, 17122L,
1L, NA)), .Names = c("var1", "var2", "var3"), row.names = c(NA,
15L), class = "data.frame")
  

Как я могу преобразовать эти данные в широкий формат? Я попробовал это

 reshape(h, idvar="var2", v.names="var3", timevar="var1", direction="wide")
  

но это не дает мне правильных результатов. Правильный результат:

   var1 ADLO AEA AKOKU APALA ASATAP   ATUPVA AULASU AVVAL
1  APE  NaN 101   NA      1      1 17122009     NA    NA
2  APE  NaN  10   684     1      1    17122     NA    NA
3  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   NaN
4  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   NaN
  

Ответ №1:

Отредактировано

Единственный способ получить ожидаемые результаты — добавить новый столбец в data.frame. Мне кажется, что существует некоторая скрытая информация о ваших данных, которая не содержится в данных. Другими словами, должна быть какая-то группирующая переменная, которая идентифицирует определенные записи как принадлежащие друг другу.

Поскольку я не могу дважды угадать, что это за информация, в своем ответе я собираюсь предположить, что каждое вхождение GIT обозначает конец записи:

 x <- grep("GIT", h$var1)
h$rec <- rep(seq_along(x), times=c(x[1], diff(x)))

library(reshape2)
mh <- melt(h, measure.vars="var3")
cast(mh, rec var1~var2, id.var="rec", measure.var="value", fun.aggregate=mean)

  rec var1 ADLO AEA AKOKU APALA ASATAP   ATUPVA AULASU AVVAL
1   1  APE  NaN  10   NaN     1      1 17122009     NA    NA
2   1  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   NaN
3   2  APE  NaN  10   684     1      1 17122009     NA    NA
4   2  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   Na
  

Оригинальный ответ

Я считаю, что пакет reshape2 намного проще для понимания, чем встроенная reshape функция. Этот пакет предоставляет две функции:

  • melt чтобы сделать широкий data.frame высокий
  • cast чтобы сделать высокий data.frame широкий

В вашем случае вам нужно cast :

 library(reshape2)
cast(h, var1~var2, value="var3", fun.aggregate=mean)

  var1 ADLO AEA AKOKU APALA ASATAP   ATUPVA AULASU AVVAL
1  APE  NaN  10   684     1      1 17122009     NA    NA
2  GIT   NA NaN   NaN   NaN    NaN      NaN    NaN   NaN
  

Комментарии:

1. Спасибо, но я хотел бы также иметь повторяющиеся записи, чтобы в APE было 2 строки. Теперь это группирование данных на основе var1, а не их изменение.

Ответ №2:

Я добавляю новую переменную из-за значения GIT :

  dat$id <- cumsum(dat$var1=='GIT')
  

Сначала я выполняю агрегацию:

 datMean <- aggregate(var3 ~ var2 * id, data=dat, FUN=mean)

> datMean
    var2 id     var3
1    AEA  0      101
2  APALA  0        1
3 ASATAP  0        1
4 ATUPVA  0 17122009
5    AEA  1       10
6  AKOKU  1      684
7  APALA  1        1
8 ASATAP  1        1
9 ATUPVA  1    17122
  

а затем преобразование из длинного в широкий:

 datWide <- reshape(datMean, direction='wide', idvar='id', timevar='var2')

> datWide
  id var3.AEA var3.APALA var3.ASATAP var3.ATUPVA var3.AKOKU
1  0      101          1           1    17122009         NA
5  1       10          1           1       17122        684