2017-03-13 10 views
2

xmlファイルには2つの問題があります。最初に重複した列名( "timestamp"と "id")があり、data.tableはそれらを別の列で区切る代わりに1つの列に入れます。第二に、以下のdata.tableの例は、値の担当者で満たされるべきNAの多くを生成します。xmlを列が重複するデータフレームに変換する

<Node1 timestamp="start">        
    <Node2 id="1110" Value1="345">    
     <Node3 id="500" timestamp="1">    
      <Node4 id="484663" Value2="130" Value3="1,2,3" /> 
      <Node4 id="253234" Value2="59" Value3="1,2,3" /> 
      <Node4 id="198476" Value2="131" Value3="1,2,3" /> 
     </Node3>          
     <Node3 id="501" timestamp="2"> 
      <Node4 id="305943" Value2="444" Value3="1,2,3" /> 
     </Node3> 
     <Node3 id="601" timestamp="5"> 
     </Node3> 
     <Node3 id="113" timestamp="3">    
      <Node4 id="2009343" Value2="555" Value3="1,2,3" /> 
      <Node4 id="2530931" Value2="333" /> 
      <Node4 id="1984761" Value2="111" Value3="1,2,3" /> 
     </Node3>          
    </Node2>           
</Node1> 

データフレームを取得するために次の行を使用しました。しかし、多くのNAがあり、 "id"と "timestamp"の値が1つの列に混在しています。どうやってdata.tableに3つのid colを生成させ、NAを入れたり書くのではなく、値を繰り返すことができますか?

library(data.table)                  
library(XML)                    
# test.xml = the xml-file 

test <- xmlTreeParse("test.xml", useInternalNodes=TRUE)         

Node1 <- rbindlist(lapply(test["//*"], function(x)as.list(xmlAttrs(x))), fill = TRUE, use.names = TRUE) 

結果がノードセットをループ

timestamp id  Value1 id  timestamp id  Value2 Value3 
start  1110 345  500 1   484663 130  1,2,3 
start  1110 345  500 1   253234 59  1,2,3 
start  1110 345  500 1   198476 131  1,2,3 
start  1110 345  501 2   305943 444  1,2,3 
start  1110 345  601 5   NA  NA  NA 
start  1110 345  113 3   2009343 555  1,2,3 
start  1110 345  113 3   2530931 333  NA 
start  1110 345  113 3   1984761 111  1,2,3 

答えて

0

..次のようになりますとnode1node4からノードセットを横断し、それぞれの属性値を取得するためにxmlAttrs()を使うであろう、xmlAncestorsにそれを渡す必要があります階層のレベル。 node4がない場合、トラバーサルツリー全体が無視されます。 node4を完了した後、再び同じノードを1ノード下に置いてください - node3と一緒に2つのデータをマージしてください。

b1 <- t(xpathSApply(doc, "//Node3", xmlAncestors, xmlAttrs)) 
b1 <- data.frame(matrix(unlist(b1), 
          nrow = nrow(b1), 
          ncol = ncol(b1), 
          dimnames = list(NULL, colnames(b1))), 
        stringsAsFactors = FALSE) 
b1 
# timestamp id Value1 id.1 timestamp.1 
# 1  start 1110 345 500   1 
# 2  start 1110 345 501   2 
# 3  start 1110 345 601   5 
# 4  start 1110 345 113   3 

ノード3から

仕事ノード4から

a1 <- xpathSApply(doc, "//Node4", xmlAncestors, xmlAttrs) 
a1_len <- lengths(a1) 
nm <- make.unique(names(a1[[ which(a1_len == max(a1_len))[1] ]])) 
a1 <- lapply(a1, function(x) { 
    require('data.table') 
    nm_x <- make.unique(names(x)) 

    if(! all(nm %in% nm_x)) { 
    x [ (nm [ which(! nm %in% nm_x) ]) ] <- NA 
    } 

    x <- cbind.data.frame(x, stringsAsFactors = FALSE) 
    colnames(x) <- make.unique(colnames(x)) 
    setDT(x) 
    setcolorder(x, nm) 
    return(x) 
}) 

a1 <- rbindlist(a1) 
a1 
# timestamp id Value1 id.1 timestamp.1 id.2 Value2 Value3 
# 1:  start 1110 345 500   1 484663 130 1,2,3 
# 2:  start 1110 345 500   1 253234  59 1,2,3 
# 3:  start 1110 345 500   1 198476 131 1,2,3 
# 4:  start 1110 345 501   2 305943 444 1,2,3 
# 5:  start 1110 345 113   3 2009343 555 1,2,3 
# 6:  start 1110 345 113   3 2530931 333  NA 
# 7:  start 1110 345 113   3 1984761 111 1,2,3 

仕事はA1とB1をマージ:

merge(a1, b1, all = TRUE) 
# timestamp id Value1 id.1 timestamp.1 id.2 Value2 Value3 
# 1:  start 1110 345 113   3 2009343 555 1,2,3 
# 2:  start 1110 345 113   3 2530931 333  NA 
# 3:  start 1110 345 113   3 1984761 111 1,2,3 
# 4:  start 1110 345 500   1 484663 130 1,2,3 
# 5:  start 1110 345 500   1 253234  59 1,2,3 
# 6:  start 1110 345 500   1 198476 131 1,2,3 
# 7:  start 1110 345 501   2 305943 444 1,2,3 
# 8:  start 1110 345 601   5  NA  NA  NA 

データ:

library('XML') 
doc <- xmlParse(' <Node1 timestamp="start">        
    <Node2 id="1110" Value1="345">    
       <Node3 id="500" timestamp="1">    
       <Node4 id="484663" Value2="130" Value3="1,2,3" /> 
       <Node4 id="253234" Value2="59" Value3="1,2,3" /> 
       <Node4 id="198476" Value2="131" Value3="1,2,3" /> 
       </Node3>          
       <Node3 id="501" timestamp="2"> 
       <Node4 id="305943" Value2="444" Value3="1,2,3" /> 
       </Node3> 
       <Node3 id="601" timestamp="5"> 
       </Node3> 
       <Node3 id="113" timestamp="3">    
       <Node4 id="2009343" Value2="555" Value3="1,2,3" /> 
       <Node4 id="2530931" Value2="333" /> 
       <Node4 id="1984761" Value2="111" Value3="1,2,3" /> 
       </Node3>          
       </Node2>           
       </Node1> ') 
関連する問題