这个问题的版本之前已经被问过了,就像这里和这里一样。但是,我仍然无法让它工作。我正在尝试将 XML 文档解析为数据框。问题是某些变量不存在某些观察结果,因此我收到错误消息,因为行数不同。我的数据如下所示:
library("xml2")
library("dplyr")
example <- read_xml(
'
<particDesc>
<person role="participant" sameAs="#P484" xml:id="EDcon250_S1">
<age value="3">35-49</age>
<sex value="1">male</sex>
<occupation>waiter</occupation>
<langKnowledge>
<langKnown level="L1" tag="ita"/>
</langKnowledge>
</person>
<person role="participant" sameAs="#P485" xml:id="EDcon250_S7">
<age value="0">unknown</age>
<sex value="2">female</sex>
<occupation>waitress</occupation>
<langKnowledge>
<langKnown level="L1" tag="ger-AT"/>
</langKnowledge>
</person>
<person role="participant" sameAs="#P465" xml:id="EDcon250_S2">
<age value="2">25-34</age>
<sex value="2">female</sex>
<langKnowledge>
<langKnown level="L1" tag="ger-AT"/>
<langKnown level="L1" tag="eng-US"/>
</langKnowledge>
</person>
</particDesc>
')
我正在使用 Wickham 的xml2
包来读取 xml。XML
我更喜欢使用这个包,但如果这是解决这个问题的最佳(或唯一)方法,我会愿意使用。无论如何,我的代码如下:
participants <- xml_find_all(example, './/person[@role = "participant"]')
extract_participants <- function(div){
id <- xml_attr(div, "id")
same_as <- xml_attr(div, "sameAs")
role <- xml_attr(div, "role")
age <- xml_find_all(div, ".//age") %>% xml_text()
sex <- xml_find_all(div, ".//sex") %>% xml_text()
occupation <- xml_find_all(div, ".//occupation") %>% xml_text()
data_frame(id, same_as,role, age, sex, occupation)
}
parts_ls <- lapply(participants, extract_participants)
participants_df <- do.call(rbind, parts_ls)
这个特定的问题涉及occupation
变量(第三人没有变量),但在我的实际数据中,它也可能是其他变量之一。正如我所说,我可以看到之前已经提出过这个问题,但是我可以获得任何可行的建议(可能是由于我没有完全理解解决方案)。最终,我希望在缺少特定节点时返回 NA(因此occupation
第三人的变量将是NA
.
编辑时:这是替代XML
版本
library("XML")
library("magrittr")
example2 <- xmlParse(
'
<particDesc>
<person role="participant" sameAs="#P484" xml:id="EDcon250_S1">
<age value="3">35-49</age>
<sex value="1">male</sex>
<occupation>waiter</occupation>
<langKnowledge>
<langKnown level="L1" tag="ita"/>
</langKnowledge>
</person>
<person role="participant" sameAs="#P485" xml:id="EDcon250_S7">
<age value="0">unknown</age>
<sex value="2">female</sex>
<occupation>waitress</occupation>
<langKnowledge>
<langKnown level="L1" tag="ger-AT"/>
</langKnowledge>
</person>
<person role="participant" sameAs="#P465" xml:id="EDcon250_S2">
<age value="2">25-34</age>
<sex value="2">female</sex>
<langKnowledge>
<langKnown level="L1" tag="ger-AT"/>
<langKnown level="L1" tag="eng-US"/>
</langKnowledge>
</person>
</particDesc>
')
example_root <- xmlRoot(example2)
process <- function(x){
id <- xmlGetAttr(x, "id")
role <- xmlGetAttr(x, "role")
age <- getNodeSet(x, ".//age") %>% xmlSApply(xmlValue)
sex <- getNodeSet(x, ".//sex") %>% xmlSApply(xmlValue)
#occupation <- getNodeSet(x, ".//occupation") %>% xmlSApply(xmlValue)
data.frame(id = id,
role = role,
#occupation = occupation,
age = age,
sex = sex,
stringsAsFactors = FALSE)
}
ls <- xpathApply(example_root, "//person", process)
df <- do.call(rbind, ls)
只需取消注释occupation
即可查看问题。