R语言实现:除指定列外批量转数值型并嵌套数据
动态处理多结构XML文件转嵌套DataFrame
问题背景
需要批量处理结构略有差异的XML文件,每个文件生成一个嵌套DataFrame。原代码固定指定m1/m2/m3列转换数值型,遇到包含m4列的文件会报错,同时需要自动将除identite类变量外的所有数据嵌套。
解决方案代码
if(!require(tidyverse)) install.packages("tidyverse") if(!require(xml2)) install.packages("xml2") if(!require(lubridate)) install.packages("lubridate") # 定义单文件处理函数 process_xml_file <- function(file_path) { # 读取并解析XML doc <- xml2::read_xml(file_path) %>% xml2::as_list() %>% purrr::pluck("bilans","bilan") # 提取identite核心信息 identite <- tibble::tibble( siren = doc %>% purrr::pluck("identite", "siren", 1), code_greffe = doc %>% purrr::pluck("identite", "code_greffe", 1), date_cloture_ex = doc %>% purrr::pluck("identite", "date_cloture_exercice", 1) %>% lubridate::as_date(), date_cloture_ex_n.1 = doc %>% purrr::pluck("identite", "date_cloture_exercice_n-1", 1) %>% lubridate::as_date(), duree_exercice_n = doc %>% purrr::pluck("identite", "duree_exercice_n", 1), duree_exercice_n.1 = doc %>% purrr::pluck("identite", "duree_exercice_n-1", 1), statut_saisie = doc %>% purrr::pluck("identite", "code_motif", 1), type_bilan = doc %>% purrr::pluck("identite", "code_type_bilan", 1), confidentialite = doc %>% purrr::pluck("identite", "code_confidentialite", 1), nom = doc %>% purrr::pluck("identite", "denomination", 1) ) # 提取detail模块的属性数据 data <- doc %>% purrr::pluck("detail") %>% purrr::map_df(~purrr::map_df(.,~attributes(.))) # 动态转换:除code列外所有列转为数值型 data_num <- data %>% dplyr::mutate(dplyr::across(-code, as.numeric)) # 合并数据并自动嵌套非identite列 full <- dplyr::bind_cols(identite, data_num) full_nested <- full %>% tidyr::nest(data = !names(identite)) return(full_nested) } # 批量处理示例:替换为你的XML文件目录路径 xml_files <- list.files(path = "./xml_files", pattern = "*.xml", full.names = TRUE) all_results <- purrr::map(xml_files, process_xml_file)
关键改进点
- 动态数值转换:使用
dplyr::across(-code, as.numeric)自动识别所有非code的列(包括m1/m2/m3/m4等)并转换为数值型,避免固定列名导致的报错。 - 自动嵌套:通过
nest(data = !names(identite))自动将所有不属于identite的列嵌套到data列中,无需手动指定列名,适配不同XML的结构差异。 - 批量处理:封装为函数后,结合
purrr::map可以一次性处理目录下所有XML文件。
XML示例
<?xml version="1.0" encoding="UTF-8"?> <bilans xmlns="fr:inpi:odrncs:bilansSaisisXML" version="1.0"> <bilan> <identite> <siren>7541834956</siren> <date_cloture_exercice>20210101</date_cloture_exercice> <code_greffe>7803</code_greffe> <num_depot>0945383</num_depot> <num_gestion>1945852</num_gestion> <code_activite>4332B</code_activite> <date_cloture_exercice_n-1>0439543851</date_cloture_exercice_n-1> <duree_exercice_n>12</duree_exercice_n> <duree_exercice_n-1>12</duree_exercice_n-1> <date_depot>20210210</date_depot> <code_motif>00</code_motif> <code_type_bilan>S</code_type_bilan> <code_devise>EUR</code_devise> <code_origine_devise>O</code_origine_devise> <code_confidentialite>0</code_confidentialite> <info_traitement /> <denomination><![CDATA[hidden]]></denomination> <adresse><![CDATA[nowhere]]></adresse> </identite> <detail> <page numero="01"> <liasse code="014" m1="000000000001671" m2="000000000001671" /> <liasse code="028" m1="000000000021557" m2="000000000019525" m3="000000000002032" /> <liasse code="040" m1="000000000001049" m3="000000000001049" /> <liasse code="044" m1="000000000024277" m2="000000000021196" m3="000000000003081" /> <liasse code="050" m1="000000000060031" m3="000000000060031" /> <liasse code="068" m1="000000000040570" m2="000000000002193" m3="000000000038376" /> <liasse code="072" m1="000000000009806" m3="000000000009806" /> <liasse code="084" m1="000000000032908" m3="000000000032908" /> <liasse code="092" m1="000000000004742" m3="000000000004742" /> <liasse code="096" m1="000000000148057" m2="000000000002193" m3="000000000145863" /> <liasse code="110" m1="000000000172334" m2="000000000023390" m3="000000000148944" /> <liasse code="120" m3="000000000007600" /> <liasse code="126" m3="000000000000760" /> <liasse code="134" m3="-000000000044214" /> <liasse code="136" m3="-000000000012606" /> <liasse code="142" m3="-000000000048461" /> <liasse code="156" m3="000000000049178" /> <liasse code="166" m3="000000000071965" /> <liasse code="169" m2="000000000029740" /> <liasse code="172" m3="000000000076261" /> <liasse code="176" m3="000000000197405" /> <liasse code="180" m3="000000000148944" /> <liasse code="182" m3="000000000001415" /> </page> <page numero="02"> <liasse code="214" m1="000000000031915" /> <liasse code="218" m1="000000000266718" /> <liasse code="222" m1="000000000000835" /> <liasse code="230" m1="000000000000178" /> <liasse code="232" m1="000000000299646" /> <liasse code="238" m1="000000000083038" /> <liasse code="240" m1="000000000001500" /> <liasse code="242" m1="000000000075261" /> <liasse code="243" m1="-000000000000411" /> <liasse code="244" m1="000000000003279" /> <liasse code="250" m1="000000000100069" /> <liasse code="252" m1="000000000045326" /> <liasse code="254" m1="000000000001384" /> <liasse code="256" m1="000000000002000" /> <liasse code="262" m1="000000000000007" /> <liasse code="264" m1="000000000311863" /> <liasse code="270" m1="-000000000012217" /> <liasse code="290" m1="000000000000564" /> <liasse code="294" m1="000000000000024" /> <liasse code="300" m1="000000000000930" /> <liasse code="310" m1="-000000000012606" /> </page> </detail> </bilan> </bilans>
内容的提问来源于stack exchange,提问作者Greg Mansio
相关产品推荐
相关产品推荐

