XML转DataFrame后仅一行多列,寻求拆分解决方法
解决XML转DataFrame时行列颠倒的问题
你的问题出在对XML节点的遍历逻辑上:原代码直接对根节点执行嵌套xmlSApply,把所有字段的内容扁平化拼接成了一个大列表,转置后自然变成一行多列的结构。正确的做法是先定位到存储每行数据的节点集合,再逐个提取每行的字段值,最后组合成标准的DataFrame。
基于XML包的修正方案
首先修正原URL的拼写错误(原链接中的legedr.xml应为rows.xml,否则无法获取正确数据),然后调整节点遍历逻辑:
library(XML) library(RCurl) fileURL <- "https://data.ny.gov/api/views/ngbt-9rwf/rows.xml" xml_doc <- xmlTreeParse(getURL(fileURL), useInternalNodes = TRUE) xmltop <- xmlRoot(xml_doc) # 定位到存储数据的行节点集合(根节点下第二个子节点为数据容器) data_node <- xmlChildren(xmltop)[[2]] row_nodes <- xmlChildren(data_node) # 遍历每个行节点,提取字段名和对应值 row_data_list <- lapply(row_nodes, function(row) { field_nodes <- xmlChildren(row) sapply(field_nodes, xmlValue) }) # 将列表转换为DataFrame plantcat_df <- do.call(rbind, lapply(row_data_list, function(x) { data.frame(t(x), stringsAsFactors = FALSE, row.names = NULL) })) View(plantcat_df)
更简洁的xml2包方案
推荐使用更现代的xml2包结合tidyverse工具,语法更直观且不易出错:
library(xml2) library(tidyverse) fileURL <- "https://data.ny.gov/api/views/ngbt-9rwf/rows.xml" xml_doc <- read_xml(fileURL) # 用XPath定位所有行节点 row_nodes <- xml_find_all(xml_doc, ".//row") # 提取每行的字段并转换为宽表结构 plantcat_df <- row_nodes %>% map_dfr(function(row) { cols <- xml_children(row) tibble( field_name = xml_name(cols), field_value = xml_text(cols) ) %>% pivot_wider(names_from = field_name, values_from = field_value) }) View(plantcat_df)
关键说明
- 原URL的拼写错误是潜在问题:
legedr.xml是无效路径,正确路径为rows.xml,否则会获取错误的XML结构。 - 核心逻辑是先按行拆分节点:每个
<row>节点对应DataFrame的一行,节点内的子元素对应列,这样就能得到正常的行列结构。
内容的提问来源于stack exchange,提问作者Yuri Rolimus
相关产品推荐
相关产品推荐

