Eme*_*mer 13 xml r list dataframe
我必须应对一个丑陋的名单ul
,看起来像这样:
[[1]]
[[1]]$param
name value
"Section" "1"
[[1]]$param
name value
"field" "1"
[[1]]$param
name value
"final answer" "1"
[[1]]$param
name value
"points" "-0.0"
[[2]]
[[2]]$param
name value
"Section" "1"
[[2]]$param
name value
"field" "2"
[[2]]$param
name value
"final answer" "1"
[[2]]$param
name value
"points" "1.0"
[[3]]
[[3]]$param
name value
"Section" "1"
[[3]]$param
name value
"field" "3"
[[3]]$param
name value
"final answer" "0.611"
[[3]]$param
name value
"points" "1.0"
Run Code Online (Sandbox Code Playgroud)
我想将列表转换为简单的数据框,即
Section field final answer points
1 1 1 -0.0
1 2 1 1.0
1 3 0.611 1.0
Run Code Online (Sandbox Code Playgroud)
有没有直接的方法来实现这一目标?或者我是否必须单独访问每个列表并将其绑定到数据帧?
数据是从uglier xml文件导入的,因此如果有人想要使用它,则会有一个指向RData文件的链接.很抱歉没有可重现的代码.非常感谢你.
csg*_*pie 12
可能有更好的解决方案,但这应该让你开始.首先,我们加载一些库
R> library(plyr)
R> library(reshape2)
Run Code Online (Sandbox Code Playgroud)
然后分两部分处理您的列表.
##lapply applies ldply to each list element in turn
ul1 = lapply(ul, ldply)
##We then do the same again
dd = ldply(ul1)[,2:3]
Run Code Online (Sandbox Code Playgroud)
接下来,我们根据列表顺序标记输出
R> dd$num = rep(1:3, each=4)
Run Code Online (Sandbox Code Playgroud)
然后我们从长格式转换为宽格式
R> dcast(dd, num ~ name)
num field final answer points Section
1 1 1 1 -0.0 1
2 2 2 1 1.0 1
3 3 3 0.611 1.0 1
Run Code Online (Sandbox Code Playgroud)
raf*_*lle 10
Marc Schwartz在此链接中给出了类似问题的答案:https: //stat.ethz.ch/pipermail/r-help/2006-August/111368.html
我正在复制它以防链接被删除.
as.data.frame(sapply(a, rbind))
V1 V2 V3
1 a b c
2 1 3 5
3 2 4 6
Run Code Online (Sandbox Code Playgroud)
要么:
as.data.frame(t(sapply(a, rbind)))
V1 V2 V3
1 a 1 2
2 b 3 4
3 c 5 6
Run Code Online (Sandbox Code Playgroud)
由于结构ul
是一致的,您可以单独获取每个列(仅使用基数R):
section <- vapply(ul, function(x) as.numeric(x[[1]][2]), 0)
field <- vapply(ul, function(x) as.numeric(x[[2]][2]), 0)
final_answer <- vapply(ul, function(x) as.numeric(x[[3]][2]), 0)
points <- vapply(ul, function(x) as.numeric(x[[4]][2]), 0)
Run Code Online (Sandbox Code Playgroud)
(注意,我使用vapply
而不是sapply
因为它更快并且可靠地返回向量,这是需要的).
然后你可以简单地把它们放在一起:
> data.frame(section, field, final_answer, points)
section field final_answer points
1 1 1 1.000 0
2 1 2 1.000 1
3 1 3 0.611 1
Run Code Online (Sandbox Code Playgroud)
请注意,我将一切都变成了numeric
.如果你想保留一切字符,删除as.numeric
和交换0
与""
在每次调用vapply
.
延迟更新:
实际上有一个很好的oneliner可以提取完整的数据:
do.call("rbind", lapply(ul, function(x) as.numeric(vapply(x, "[", i = 2, ""))))
Run Code Online (Sandbox Code Playgroud)
这使:
[,1] [,2] [,3] [,4]
[1,] 1 1 1.000 0
[2,] 1 2 1.000 1
[3,] 1 3 0.611 1
Run Code Online (Sandbox Code Playgroud)
得到colnames
使用:
> vapply(ul[[1]], "[", i = 1, "")
param param param param
"Section" "field" "final answer" "points"
Run Code Online (Sandbox Code Playgroud)