在R中将clinicaltrials.gov嵌套XML转换为DataFrame的问题
解决clinicaltrials.gov XML数据转R DataFrame的多值地点字段展开问题
错误原因分析
你之前遇到的unnest()报错,是因为直接对所有列表字段执行展开操作时,非地点类多值字段(如Condition、Keyword)的元素数量与地点数量不匹配,导致tidyr无法完成循环回收(比如某研究有3个地点,但Condition有2个值,3和2无法对应)。
解决方案
核心思路是:仅针对地点相关字段进行组合与展开,保留其他非地点字段的原样(自动重复),避免不同多值字段的数量冲突。具体步骤如下:
完整代码实现
library(tidyverse) library(xml2) # 目标API URL url1 <- "https://classic.clinicaltrials.gov/api/query/study_fields?expr=&fields=NCTId%2C+OrgFullName%2C+BriefTitle%2C+StartDate%2C+Condition%2C+Keyword%2C+InterventionName%2C+EnrollmentCount%2C+LocationFacility%2C+LocationCity%2C+LocationState%2C+LocationZip%2C+LocationCountry&min_rnk=1&max_rnk=1000&fmt=xml" # 读取XML并转换为结构化列表 dat_list <- read_xml(url1) %>% as_list() # 提取所有StudyFields节点并转换为tibble(自动处理单值/多值字段为列表) study_data <- dat_list$StudyFieldsResponse$StudyFields %>% map_dfr(~ as_tibble(.x, .name_repair = "unique")) %>% # 清理重复的列名后缀(如...1) rename_with(~ str_remove(., "\\.\\.\\.\\d+")) # 组合地点字段并展开为多行 study_data_final <- study_data %>% # 将每个研究的所有地点字段组合成嵌套的tibble mutate( location = pmap( list(LocationFacility, LocationCity, LocationState, LocationZip, LocationCountry), ~ tibble( facility = unlist(..1), city = unlist(..2), state = unlist(..3), zip = unlist(..4), country = unlist(..5) ) ) ) %>% # 移除原始地点字段 select(-starts_with("Location")) %>% # 展开地点嵌套列,每个地点对应一行记录 unnest(location) %>% # 自动转换数据类型(可选) type_convert()
验证结果
执行后,每个研究的多个地点会生成独立行,核心字段(如NCTId、BriefTitle)自动重复:
# 查看第206条研究的地点展开结果 glimpse(study_data_final %>% filter(NCTId == study_data_final$NCTId[206]))
输出示例:
Rows: 2 Columns: 10 $ NCTId <chr> "NCTxxxxxxx", "NCTxxxxxxx" $ OrgFullName <chr> "某研究机构", "某研究机构" $ BriefTitle <chr> "某研究标题", "某研究标题" $ StartDate <chr> "2023-01-01", "2023-01-01" $ Condition <list> [["糖尿病"]] $ Keyword <list> [["临床试验", "降糖"]] $ InterventionName <list> [["药物A"]] $ EnrollmentCount <int> 100, 100 $ facility <chr> "堪萨斯城医疗中心", "哥伦布临床中心" $ city <chr> "Kansas City", "Columbus" $ state <chr> "Kansas", "Ohio" $ zip <chr> "66160", "43210" $ country <chr> "United States", "United States"
额外说明
如果需要处理其他多值字段(如Condition、Keyword),可以在上述代码基础上单独展开,例如:
# 展开Condition字段(每个条件-地点组合生成一行) study_data_final %>% unnest_longer(Condition)
内容的提问来源于stack exchange,提问作者Russell Morgan
相关产品推荐
相关产品推荐

