我有以下列表:
$id1
$id1[[1]]
A B
"A" "B"
$id1[[2]]
A B
"A" "A1"
$id2
$id2[[1]]
A B
"A2" "B2"
以R-pastable形式:
dat = structure(list(SampleTable = structure(list(id2 = list(structure(c("90", "7"), .Names = c("T", "G")), structure(c("90", "8"), .Names = c("T", "G"))), id1 = structure(c("1", "1"), .Names = c("T", "G"))), .Names = c("id2", "id1"))), .Names = "SampleTable")
我希望将此给定列表转换为以下数据帧:
id1 A B
id1 A A1
id2 A2 B2
答案 0 :(得分:5)
您的数据结构(显然是未命名的1行data.frames列表的命名列表)有点复杂:最简单的可能是使用循环来构建data.frame。
可以直接使用do.call
,lapply
和rbind
来完成,但即使您熟悉这些功能,它也不是非常易读。
# Sample data
d <- list(
id1 = list(
data.frame( x=1, y=1 ),
data.frame( x=2, y=2 )
),
id2 = list(
data.frame( x=3, y=3 ),
data.frame( x=4, y=4 )
),
id3 = list(
data.frame( x=5, y=5 ),
data.frame( x=6, y=6 )
)
)
# Convert
d <- data.frame(
id=rep(names(d), unlist(lapply(d,length))),
do.call( rbind, lapply(d, function(u) do.call(rbind, u)) )
)
其他解决方案,使用循环,如果你有一个参差不齐的数据结构,包含矢量(而不是data.frames),如评论中所述。
d <- structure(list(SampleTable = structure(list(id2 = list(structure(c("90", "7"), .Names = c("T", "G")), structure(c("90", "8"), .Names = c("T", "G"))), id1 = structure(c("1", "1"), .Names = c("T", "G"))), .Names = c("id2", "id1"))), .Names = "SampleTable")
result <- list()
for(i in seq_along(d$SampleTable)) {
id <- names(d$SampleTable)[i]
block <- d$SampleTable[[i]]
if(is.atomic(block)) {
block <- list(block)
}
for(row in block) {
result <- c(result, list(data.frame(id, as.data.frame(t(row)))))
}
}
result <- do.call(rbind, result)
答案 1 :(得分:1)
请注意!我无法融化并投射这种粗糙的数据(我尝试了一个多小时......)我将在这里留下这个答案,以表明对于这种操作,也可以使用重塑的pacakge。
使用vincent的示例数据,您可以使用reshape包中的melt和cast:
library(reshape)
res = cast(melt(d))[-1]
names(res) = c("id","x","y")
res
id x y
1 id1 1 1
2 id2 3 3
3 id3 5 5
4 id1 2 2
5 id2 4 4
6 id3 6 6
结果data.frame中的顺序不一样,但结果是相同的。代码有点短。我使用[-1]
删除melt
也返回的第一列。此附加变量是列表列表中各个data.frames的列索引。看看melt(d)
的结果,希望能让它更清晰。
答案 2 :(得分:0)
这让你有点麻烦。 dat
对象上方有一个额外的“图层”,因此使用dat[[1]]
更容易:
dfrm <- data.frame(dat[[1]], stringsAsFactors=FALSE)
names(dfrm) <- sub("\\..+$", "", names(dfrm))
> dfrm
id2 id2 id1
T 90 90 1
G 7 8 1
> t(dfrm)
T G
id2 "90" "7"
id2 "90" "8"
id1 "1" "1"