我有一个看起来像这样的xml:
...
<node id=1>
<child>a</child>
<child>b</child>
<child>c</child>
</node>
<node id=2>
<child>d</child>
<child>e</child>
</node>
...
我正在寻找的是一个data.frame,指的是孩子的父母:
node_id child_text
1 a
1 b
1 c
2 d
2 e
我只能想到使用xml2的两种解决方案:
(a)使用xml_find_all(...)创建一组子节点,然后使用for循环来操纵xml结构以获取所需信息。显然非常低效。
(b)获取一组父节点和一组子节点。从父集中提取信息并计算每个父母拥有的子女数。然后使用rep(information,no_of_children)从上面填充node_id列。更好但仍然很愚蠢。
我认为必须有更有效的方法吗?我很高兴有任何建议,因为我现在使用这些方法已经超过一个月了,同时处理xigabites - 非常低效 - xml格式的数据结构。我也不仅限于使用xml2,也可以切换到另一种编程语言,如果这会大大提高性能。唯一重要的部分是我想从那里直接将数据加载到数据库中。
答案 0 :(得分:0)
鉴于您提供的非常通用的示例,我将rvest
与purrr
一起使用:
x <- "<node id=1>
<child>a</child>
<child>b</child>
<child>c</child>
</node>
<node id=2>
<child>d</child>
<child>e</child>
</node>"
library(rvest)
library(purrr)
read_html(x) %>%
html_nodes('node') %>%
map_df(~{
.x %>%
html_nodes('child') %>%
html_text() -> child
data.frame(child = child, stringsAsFactors = FALSE)
}, .id = 'node')
#> node child
#> 1 1 a
#> 2 1 b
#> 3 1 c
#> 4 2 d
#> 5 2 e
与您的方法进行比较的一些基准:
rbenchmark::benchmark(read_html(xml) %>%
html_nodes('node') %>%
map_df(~{
.x %>%
html_nodes('child') %>%
html_text() -> child
data.frame(child = child, stringsAsFactors = FALSE)
}, .id = 'node'), columns = c('replications', 'elapsed', 'user.self'))
#> replications elapsed user.self
#> 1 100 0.964 0.964