提问人:Sanam 提问时间:2/9/2023 更新时间:2/9/2023 访问量:39
从 XML 中提取数据框(文本),但文件在 R 中具有重复的节点名称
Extract data frame (text) from XML, but file has duplicated node names in R
问:
我有一个正在处理的 XML 文件,并试图让输出看起来像您在 R 中使用函数时的样子。但是,我的文件太复杂了,所以这个函数对我不起作用,并且由于节点名称重复且不唯一而给我带来错误。我附上我的 XML 文件的简化版本只是为了了解我想要实现的目标xmlToDataFrame()
<HelloWorld created="2022-03-22" id="12we">
<myname>omi</myname>
</HelloWorld>
<HelloWorld created="2022-03-12" id="18we">
<myh>59</myh>
<myfname>Tom</myfname>
<mylname>John</mylname>
</HelloWorld>
<HelloWorld created="2022-03-30" id="188yye">
<myh>60</myh>
<favcolor>grey</favcolor>
<myfname>Alex</myfname>
<mylname>Tom</mylname>
</HelloWorld>
由此,我希望生成以下输出
编号 | 我的姓名 | 马赫 | myfname | mylname | 最喜欢的颜色 |
---|---|---|---|---|---|
12我们 | 近江 | 那 | 那 | 那 | 那 |
18我们 | 那 | 59 | 汤姆 | John | 那 |
188年YYE | 那 | 60 | 亚历克斯 | 汤姆 | 灰色 |
我是XML的新手,尝试了各种方法,但仍然无法正确提取数据。任何帮助将不胜感激。
答:
0赞
r2evans
2/9/2023
#1
# library(xml2)
xml <- xml2::read_html("quux.xml") |> xml2::as_list()
## either data.table or dplyr ...
out <- dplyr::bind_rows(xml$html$body)
out <- data.table::rbindlist(xml$html$body, use.names = TRUE, fill = TRUE)
out
# # A tibble: 3 × 5
# myname myh myfname mylname favcolor
# <list> <list> <list> <list> <list>
# 1 <chr [1]> <NULL> <NULL> <NULL> <NULL>
# 2 <NULL> <chr [1]> <chr [1]> <chr [1]> <NULL>
# 3 <NULL> <chr [1]> <chr [1]> <chr [1]> <chr [1]>
由于 xml 的结构,所有列都是列表列。由于我们很满意所有元素的长度为 0 或 1,因此我们可以遍历所有元素以提取第一个元素:
out[] <- lapply(out, function(z) sapply(z, function(y) if (is.null(y)) NA else unlist(y)[1]))
out
# # A tibble: 3 × 5
# myname myh myfname mylname favcolor
# <chr> <chr> <chr> <chr> <chr>
# 1 omi NA NA NA NA
# 2 NA 59 Tom John NA
# 3 NA 60 Alex Tom grey
数据:包含内容的文件:quux.xml
<HelloWorld created="2022-03-22" id="12we">
<myname>omi</myname>
</HelloWorld>
<HelloWorld created="2022-03-12" id="18we">
<myh>59</myh>
<myfname>Tom</myfname>
<mylname>John</mylname>
</HelloWorld>
<HelloWorld created="2022-03-30" id="188yye">
<myh>60</myh>
<favcolor>grey</favcolor>
<myfname>Alex</myfname>
<mylname>Tom</mylname>
</HelloWorld>
评论
0赞
Sanam
2/10/2023
当我运行 bind_rows 或 rbindlist 时,它适用于简化的数据集,但在我的实际数据集上,我得到的输出为 0 行。你知道是什么原因造成的吗
0赞
r2evans
2/10/2023
不,我没有,您需要更新示例数据以重现 0 输出条件。也许问题出在 / 之后。使用我的代码作为模板,也许如果它不是太大,您可以提供 .read_xml
as_list
dput(xml)
0赞
Sanam
2/10/2023
我认为问题在于,在实际数据中,我们有不同长度的元素,而不仅仅是长度 0 或 1。我收到以下错误:“第 1 项的第 1 列的长度为 7,与第 7 列的长度不一致,第 7 列的长度为 27。只有长度-1的色谱柱被回收”
0赞
r2evans
2/10/2023
这是将可变格式 XML 转换为刚性结构的常见问题。不幸的是,没有一个功能可以做你想做的事。当我查看此示例数据时,我曾经查看过组件,这就是我发现它可以作为起点的方式。如果你的嵌套数据有任意长度(不仅仅是你说的 0/1),那么也许看看 after ,without ,看看事情是什么样子的。同样,没有单一的解决方案,它是一个过程,它对 XML 结构太敏感而无法概括。data.frame
str(xml)
xml$html$body
out
bind_rows
lapply
评论