将不同长度的列表组合成数据框
Combining lists of different lengths into data frame
我有像下面的 SampleData 这样的数据,它有不同长度的列表,我想将它们组合成一个数据框,比如下面的 Desired Result。我试过使用 qpcR 包中的 lapply 和 cbind.na ,如下例所示,但出于某种原因,它不允许我将结果转换为数据框。如果我只使用了两个列表和 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)
我查看您的数据的第一直觉是,通过使用 data.frame
,您是在隐含地声明一行中的项目是 成对的 。也就是说,在您的示例中,$V1
的“3”和 $V3
的“6”旨在相互关联。 (如果您查看 mtcars
,第一行的每一列 直接 和 单独 与 "Mazda RX4" 关联。 ) 如果这不是真的,那么将它们扭曲成这样的 data.frame
是在错误地表示您的数据,并鼓励不正确的 analysis/assumptions.
假设它们实际上是 "paired",我的下一个直觉是尝试 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
我有像下面的 SampleData 这样的数据,它有不同长度的列表,我想将它们组合成一个数据框,比如下面的 Desired Result。我试过使用 qpcR 包中的 lapply 和 cbind.na ,如下例所示,但出于某种原因,它不允许我将结果转换为数据框。如果我只使用了两个列表和 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)
我查看您的数据的第一直觉是,通过使用 data.frame
,您是在隐含地声明一行中的项目是 成对的 。也就是说,在您的示例中,$V1
的“3”和 $V3
的“6”旨在相互关联。 (如果您查看 mtcars
,第一行的每一列 直接 和 单独 与 "Mazda RX4" 关联。 ) 如果这不是真的,那么将它们扭曲成这样的 data.frame
是在错误地表示您的数据,并鼓励不正确的 analysis/assumptions.
假设它们实际上是 "paired",我的下一个直觉是尝试 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