在tidyverse管道中同时获取xml_attrs和xml_text。

问题描述 投票:1回答:1

我正试图使用tidyverse管道将XML转换为tibble。节点有attrs和文本。

输入。

txt <- c('<node attrA="1A" attrB="1B">text1</node>',
         '<node attrA="2A" attrB="2B">text2</node>')

希望的输出(作为一个tibble)

~attrA, ~attrB, ~text,
1A, 1B, text1,
2A, 2B, text2

我可以得到xml_attr,使用这个方便的答案。tidyverse - 把命名的向量转换成data.frametibble的首选方法。

library(xml2)
library(tidyverse)

txt <- c('<node attrA="1A" attrB="1B">text1</node>',
         '<node attrA="2A" attrB="2B">text2</node>')

txt %>% 
  map(read_xml) %>% 
  map(xml_attrs) %>% 
  map_df(bind_rows) 

但这并没有得到 text1text2. 我可以只得到xml_text。

library(xml2)
library(tidyverse)

txt <- c('<node attrA="1A" attrB="1B">text1</node>',
         '<node attrA="2A" attrB="2B">text2</node>')

txt %>% 
  map(read_xml) %>%
  map(xml_text) %>%
  unlist() %>% 
  tibble(text = .)

有什么办法能把这些结合起来,通过一个管道同时得到xml_text和xml_attrs?

我试着写了一个函数来获取一个xml节点,并在上面运行xml_text和xml_attrs,然后映射该函数,但我不能让它工作(与xml_text和xml_attrs有关)。externalptrs xml2使用的?)

我想我真正问的是一个关于 "重用 "管道中传递的东西的问题,所以我猜测答案是与 . 作为别称。

编辑:嗯嗯,也许是 as_list 是这里的一个解决方案(尽管我还是喜欢调用xml_attrs和xml_text带来的控制。

txt %>% 
  map(read_xml) %>% 
  map(xml_find_all, xpath = "//node") %>% 
  map(as_list)

产生

[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[1] "text1"

attr(,"attrA")
[1] "1A"
attr(,"attrB")
[1] "1B"


[[2]]
[[2]][[1]]
[[2]][[1]][[1]]
[1] "text2"

attr(,"attrA")
[1] "2A"
attr(,"attrB")
[1] "2B"

我打赌可以做成我想要的tibble (虽然这不是我现在能做到的 :)

r purrr xml2
1个回答
1
投票

嗯,这似乎是工作,使用 . synomyn来调用节点上的两个不同方法。

txt %>% 
  map(read_xml) %>% 
  map(xml_find_all, xpath = "//node") %>% 
  tibble(text = map_chr(., xml_text),
         # attr as a tibble column, pluck needed to unpack one
         # level of list.
         xml_attr_col = map(., xml_attrs) %>% map(pluck,1)) %>% 
  select(-1) %>%  # drop original node column somehow created by tibble
  # groovy function to unnest that tibble column
  unnest_wider(xml_attr_col)
© www.soinside.com 2019 - 2024. All rights reserved.