我有一个要从中提取数据的XML文件。到目前为止,我已经设法使用tidyverse和xml2软件包进行了所有操作,但是我仍无法弄清楚如何解决XML任务中的下一个难题。
样本XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:ArchiveView>
<Notification ID="1001">
<persons>
<Timestamp>07:39:25</Timestamp>
<person type="A" name="Barney">
<uniqueUserId>2222</uniqueUserId>
</person>
</persons>
<persons>
<Timestamp>08:40:25</Timestamp>
<person type="B" name="John">
<uniqueUserId>1111</uniqueUserId>
</person>
</persons>
</Notification>
<Notification ID="1002">
<persons>
<Timestamp>14:39:25</Timestamp>
<person type="A" name="Barney">
<uniqueUserId>2222</uniqueUserId>
</person>
</persons>
</Notification>
<Notification ID="1003">
</Notification>
</ns2:ArchiveView>
由于可以分配给一个通知的最大人数为3,因此我想得到一个看起来像这样的data.frame:
ID name1 time1 type1 name2 time2 type2 name3 time3 type3
1001 Barney 07:39:25 A John 08:40:25 B NA NA NA
1002 Barney 14:39:25 A NA NA NA NA NA NA
1003 NA NA NA NA NA NA NA NA NA
到目前为止,我设法做到了:
doc <- read_xml( "./data/test.xml" )
提取所有ID
df.ID <- data.frame(
ID = xml_find_all( doc, ".//Notifications" ) %>% xml_attrs() %>% unlist() ,
stringsAsFactors = FALSE )
标识已附加人员的通知的ID
ID.with.persons <- xml_find_all( doc, ".//Notifications[ persons ]" ) %>%
xml_attrs() %>%
unlist()
创建带有附加人员的通知节点集
nodes.persons <- xml_find_all( doc, ".//Notifications[ persons ]"
我还设法获得了所有人的所有姓名(在一个向量中)
persons.name <- nodes.persons %>% xml_attr("name") %>% unlist()
我感觉自己已经很接近解决方案了,但是我无法确定如何将所有这些数据合并到一个不错的data.frame中(如上所述)。
所有建议都受到热烈的欢迎:)
最佳答案
这是一种非常熟练的方法(我对R很陌生,所以可能不太像R。)只需遍历每个元素,然后将所需的元素粘贴到向量中即可。最后将其转换为矩阵,然后将其插入数据框。这仅适用,因为有固定数量的列可用于构建矩阵。
library(xml2)
doc <- read_xml("test.xml")
row <- c()
notifications <- xml_find_all(doc, ".//Notification")
for (i in 1:length(notifications)) {
row <- c(row, xml_attr(notifications[i], "ID"))
for (j in 1:3) {
person <- xml_find_all(notifications[i], sprintf("persons[%d]", j))
if (length(person) > 0) {
row <- c(row, xml_find_chr(person, "string(./person/@name)"))
row <- c(row, xml_find_chr(person, "string(./Timestamp/text())"))
row <- c(row, xml_find_chr(person, "string(./person/@type)"))
} else {
row <- c(row, NA, NA, NA)
}
}
}
df <- data.frame(matrix(data=rows, ncol=10, byrow=TRUE))
colnames(df) <- c("ID", "name1", "time1", "type1", "name2", "time2", "type2", "name3", "time3", "type3")
df
输出:
ID name1 time1 type1 name2 time2 type2 name3 time3 type3
1 1001 Barney 07:39:25 A John 08:40:25 B <NA> <NA> <NA>
2 1002 Barney 14:39:25 A <NA> <NA> <NA> <NA> <NA> <NA>
3 1003 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
关于r - 从XML提取数据并传递到data.frame(使用NA表示丢失),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48925416/