#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