xml 解析到 R 中的数据帧

xml parsing into a dataframe in R

提问人:tetristiger 提问时间:10/15/2022 最后编辑:Parfaittetristiger 更新时间:10/15/2022 访问量:82

问:

我想在 R 中解析一个 xml 文件。这是一场德国议会辩论。我设法获得了所有(语音)元素的列表。<rede>

现在,我想将说话人的名字和演讲作为单个字符串放入数据帧中。 然后,我想打印演讲的次数和第一次演讲的内容。

这是我目前拥有的代码:

session <-read_html("https://www.bundestag.de/resource/blob/909520/ccbb1b470836b419e0e0ab726b679a99/20052-data.xml")
# session Sep 09 2022


# list of all the <rede> elements. 
speeches <- session %>% 
  html_elements("rede") %>% 
  html_text2() 

# name of the speaker, and speech as a single string
bundestag_links <- session %>% html_elements("rede")
bundestag_links

# list of lastnames (nachname) and first names (vorname)
nachname <- bundestag_links %>% html_elements("nachname") %>% html_text2()
nachname 
vorname <- bundestag_links %>% html_elements("vorname") %>% html_text2()
vorname

speaker <- do.call(rbind, Map(data.frame, vorname=vorname, nachname=nachname))  
unique(speaker$nachname)
unique(speaker$vorname)
speaker <- speaker %>% 
  distinct()

有39个发言,但有51个发言者。有些是 dublicates,因为有些人会说两次,所以删除它们实际上没有意义。

我知道还有一个用于演讲的 ID,一个用于演讲者的 ID,所以我也提取了这些信息。

# speaker ID
pattern_redner_id <- "redner id=........(\\d)"
redner_id <- bundestag_links %>% 
    str_extract(pattern_redner_id) %>% 
    str_remove_all("redner id=")
redner_id

# speech ID
pattern_rede_id <- "ID........(\\d)"
rede_id <- str_extract(bundestag_links, pattern_rede_id)
rede_id

我也设法将其中一个演讲放入一个单独的字符串中。

speakerspeech_1 <- bundestag_links[1] %>% html_elements("p[klasse!=redner]") %>% paste(collapse = " ")
speakerspeech_1

我是解析的新手,对编码相对陌生,不知道如何将这些信息组合到一个数据帧中。

我感谢任何帮助和建议。

R 循环 XML 文本解析

评论


答:

1赞 Parfait 10/15/2022 #1

考虑将 XPath 与 package 一起使用,以解析每个节点下所需的内容并将数据绑定在一起xml2<rede>

library(xml2)

url <- paste0(
  "https://www.bundestag.de/resource/blob/909520/",
  "ccbb1b470836b419e0e0ab726b679a99/20052-data.xml"
)
doc <- read_xml(url)

# RETREIVE ALL rede NODES
redes <- xml_find_all(doc, "//rede")

# BUILD A DATA FRAME OF CONTENT UNDER EACH rede
redes_dfs <- lapply(
  redes, function(r)
  data.frame(
    speech_id = xml_attr(r, "id"),
    speaker_id = sapply(xml_find_all(r, "p/redner/@id"), xml_text),
    speaker = paste(
      sapply(xml_find_all(r, "p/redner/name/vorname"), xml_text),
      sapply(xml_find_all(r, "p/redner/name/nachname"), xml_text)
    ),
    speech = paste(
      sapply(xml_find_all(r, "p[position() > 1]"), xml_text),
      collapse = " "
    )
  )
)

# BIND ALL DATA FRAMES AND DE-DUPE DATA
speeches_df <- unique(do.call(rbind, redes_dfs))

输出

str(speeches_df)
'data.frame':   40 obs. of  4 variables:
 $ speech_id : chr  "ID205200100" "ID205200200" "ID205200300" "ID205200400" ...
 $ speaker_id: chr  "999990119" "11004917" "11005200" "11004749" ...
 $ speaker   : chr  "Nancy Faeser" "Alexander Throm" "Jamila Schäfer" "Martin Hess" ...
 $ speech    : chr  "Danke schön, Frau Präsidentin...

DataFrame View