R中数据框的列表列表

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)


Hen*_*rik 9

由于结构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)