От нескольких записей для одного ID к одной в R

Стандартная ситуация - есть записи в таблице, для каждой - ID, но некоторые записи имеют один ID. Например ситуация такая, есть таблица с почвами, некоторые - чистые, а некоторые комплексы, таким образом, каждый уникальный почвенный выдел (определяется по ID) может быть представлен одной или несколькими записями.
Дальше, чтобы работать с такой таблицей при идентификации выдела можно конечно делать один-ко-многим, но хочется другого. Хочется разложить данные так, чтобы запись для одного ID была одна, а доп. данные "встали" в новые колонки.
Пример:
x = data.frame(cbind(c(1,2,2,4),trunc(runif(4,0,10)),trunc(runif(4,0,10))),trunc(runif(4,0,10)))Итак, у нас 4 записи, но 3 уникальных ID. Один из них, двойка - составной, представлен двумя записями. Решать будем так:
names(x) = c("ID","A","B","C")
x
ID A B C
1 1 0 0 4
2 2 5 4 5
3 2 1 4 7
4 4 2 7 6
- Составим список уникальных идентификаторов
- Определим максимальное количество записей на один идентификатор - частотной таблицей
- По этому числу создадим эквивалентное количество наборов полей, т.е. если были поля A B C и макс=2, то будет A B C A2 B2 C2
- Дальше выбираем данные по идентификатору, распластываем, добавляем NA недостающие до макс. числа полей и т.д.
ID A B C A1 B1 C1Полный код под катом
1 1 0 0 4 NA NA NA
2 2 5 4 5 1 4 7
3 4 2 7 6 NA NA NA
x = data.frame(cbind(c(1,2,2,4),trunc(runif(4,0,10)),trunc(runif(4,0,10))),trunc(runif(4,0,10)))
names(x) = c("ID","A","B","C")
idfname = "ID"
idfpos = which(names(x) == idfname)
#determine number of unique IDs
ids = unique(x[,idfpos])
#determine maximum number of repeats
maxrepeats = max(as.vector(table(x[,idfpos])))
#add fields
nms = names(x)
nms2 = nms
for (i in 1:(maxrepeats-1)) {
nms2 = c(nms2,paste(nms,i,sep="")[-1])
}
nms = nms2
res = NULL
for (id in ids) {
d = subset(x,x$ID == id)
y = as.numeric(d$ID[1])
for (i in 1:dim(d)[1]) {
y = c(y,as.numeric(d[i,2:length(d)]))
}
if (length(y) != length(nms)) {
y = c(y,rep(NA,length(nms)-length(y)))
}
res = rbind(res,y)
}
res = data.frame(res)
names(res) = nms