在R中合并XML父节点属性与子节点数据为单个DataFrame
一步合并XML父节点与子节点数据为单个DataFrame
当然可以!你完全可以通过直接关联每个<race>节点的父节点<meeting>来一次性提取并合并所有需要的数据,不用分开操作后再拼接。这里有两种适配你需求的方案:
方法1:基于你当前使用的XML包优化
你可以先获取所有<race>节点,然后对每个节点直接提取其父节点<meeting>的属性,把这一步整合到你的cbind操作里,实现一步生成最终DataFrame:
# 先获取所有race节点 race_nodes <- getNodeSet(CardList_tmp, "//meeting/race") # 一次性合并所有数据 CardList <- cbind( date, # 提取每个race节点对应的父meeting的id和name data.frame( meeting_id = sapply(race_nodes, function(node) xmlGetAttr(xmlParent(node), "id")), meeting_name = sapply(race_nodes, function(node) xmlGetAttr(xmlParent(node), "name")) ), # 原来的race节点属性提取 data.frame(raceid = xpathSApply(CardList_tmp, "//meeting/race", xmlGetAttr, 'id')), data.frame(cards = xpathSApply(CardList_tmp, "//meeting/race", xmlGetAttr, 'details_available')), data.frame(status = xpathSApply(CardList_tmp, "//meeting/race", xmlGetAttr, 'race_status_code')), # race节点的子节点数据 xmlToDataFrame(nodes = race_nodes) )
这个方法延续了你原有的代码风格,只是新增了通过xmlParent(node)获取父节点并提取属性的步骤,避免了分开提取course和cid后再合并的麻烦。
方法2:更简洁的xml2 + tidyverse方法
如果你愿意尝试更现代、易读的代码风格,推荐使用xml2包配合tidyverse工具链,它能让整个流程更流畅,代码更简洁:
library(xml2) library(tidyverse) # 读取XML数据(如果还没读取的话) # CardList_tmp <- read_xml("你的XML文件路径") CardList <- xml_find_all(CardList_tmp, "//meeting/race") %>% map_df(function(node) { # 获取当前race节点的父meeting节点 parent_meeting <- xml_parent(node) # 组合所有需要的数据成一行 tibble( date = date, # 假设date是你已有的变量 meeting_id = xml_attr(parent_meeting, "id"), meeting_name = xml_attr(parent_meeting, "name"), raceid = xml_attr(node, "id"), cards = xml_attr(node, "details_available"), status = xml_attr(node, "race_status_code"), # 自动提取race节点的所有子节点数据 !!!xml_contents(node) %>% set_names(xml_name(.)) %>% map(xml_text) %>% as_tibble() ) })
这个方法通过map_df遍历每个<race>节点,一次性提取父节点属性、当前节点属性以及子节点数据,自动合并成结构化的DataFrame,代码量更少,也更容易维护。
内容的提问来源于stack exchange,提问作者Tammboy
相关产品推荐
相关产品推荐

