Объединение списков разной длины в кадр данных
У меня есть данные, такие как SampleData ниже, у которых есть списки различной длины, которые я хотел бы объединить во фрейм данных, как желаемый результат ниже. Я попытался использовать lapply и cbind.na из пакета qpcR, как в примере ниже, но по какой-то причине он не позволяет мне превратить результат в кадр данных. Если я просто использовал два списка и cbind.na, он объединит их и добавит NA к концу, как я хочу, но когда я пытаюсь использовать его в lapply, он просто оставляет их как список списков разной длины. Любые советы с благодарностью.
SampleData<-list(list(1,2,3),list(1,2),list(3,4,6,7))
Desired Result:
structure(list(V1 = c(1, 2, 3, NA), V2 = c(1, 2, NA, NA), V3 = c(3,
4, 6, 7)), .Names = c("V1", "V2", "V3"), row.names = c(NA, -4L
), class = "data.frame")
Example Code:
lapply(SampleData,qpcR:::cbind.na)
2 ответа
Мой первый инстинкт просмотра ваших данных заключается в том, что, используя data.frame
Вы неявно заявляете, что элементы в ряду являются парными. То есть, в вашем примере, "3" $V1
и "6" из $V3
предназначены для связи друг с другом. (Если вы посмотрите на mtcars
, каждый столбец первого ряда связан непосредственно и исключительно с "Mazda RX4".) Если это не так, то деформируйте их в data.frame
как будто это неправильно представляет ваши данные и нравится поощрять неправильный анализ / предположения.
Предполагая, что они на самом деле "спарены", мой следующий инстинкт - попробовать что-то вроде do.call(cbind, SampleData)
, но это предоставляет переработанные данные, а не то, что вы хотите. Итак, хитрость для сдерживания рециркуляции состоит в том, чтобы заставить их быть одинаковой длины.
maxlen <- max(lengths(SampleData))
SampleData2 <- lapply(SampleData, function(lst) c(lst, rep(NA, maxlen - length(lst))))
Мы можем сначала переименовать:
names(SampleData2) <- paste("V", seq_along(SampleData2), sep = "")
Поскольку данные кажутся однородными (и должно быть, если вы намереваетесь поместить каждый элемент в виде столбца data.frame
), полезно снять список:
SampleData3 <- lapply(SampleData2, unlist)
Тогда это так же просто, как:
as.data.frame(SampleData3)
# V1 V2 V3
# 1 1 1 3
# 2 2 2 4
# 3 3 NA 6
# 4 NA NA 7
Вот модифицированная версия с length<-
назначение
setNames(do.call(cbind.data.frame, lapply(lapply(SampleData, unlist),
`length<-`, max(lengths(SampleData)))), paste0("V", 1:3))
# V1 V2 V3
#1 1 1 3
#2 2 2 4
#3 3 NA 6
#4 NA NA 7