在R中展开嵌套JSON列并保留原数据框字段时遇错如何解决?
解决R中解析JSON列合并时行数不匹配的错误
错误原因
你遇到的arguments imply differing number of rows: 0, 1错误,是因为部分行的delivery_by_region字段解析后返回0行数据框,但你在do()中直接将其与原数据的id、spend等单一行字段合并,两者行数不匹配,导致data.frame()函数报错。
解决方案
推荐使用tidyr+purrr的组合来处理,既简洁又能兼容空JSON的情况,分两种场景:
场景1:保留所有原行(解析后无数据的行对应字段设为NA)
library(tidyverse) library(jsonlite) demodf <- mergedf %>% mutate(delivery_by_region = sapply(delivery_by_region, remove_non_us)) %>% mutate(delivery_by_region = gsub("'", '"', delivery_by_region)) %>% # 安全解析JSON,空/错误JSON返回空数据框 mutate(region_data = map(delivery_by_region, ~{ parsed <- tryCatch(fromJSON(.x, flatten = TRUE), error = function(e) tibble()) if (nrow(parsed) == 0) tibble() else parsed })) %>% # 展开数据框列表,保留空行 unnest(region_data, keep_empty = TRUE) %>% # 移除原JSON字符串列(可选) select(-delivery_by_region)
场景2:仅保留解析后有区域数据的行
只需将unnest的keep_empty参数设为FALSE:
demodf <- mergedf %>% mutate(delivery_by_region = sapply(delivery_by_region, remove_non_us)) %>% mutate(delivery_by_region = gsub("'", '"', delivery_by_region)) %>% mutate(region_data = map(delivery_by_region, ~{ parsed <- tryCatch(fromJSON(.x, flatten = TRUE), error = function(e) tibble()) if (nrow(parsed) == 0) tibble() else parsed })) %>% unnest(region_data, keep_empty = FALSE) %>% select(-delivery_by_region)
兼容原有rowwise写法的修正
如果坚持使用rowwise()+do(),需要在代码中处理解析后行数为0的情况:
demodf <- mergedf %>% mutate(delivery_by_region = sapply(delivery_by_region, remove_non_us)) %>% mutate(delivery_by_region = gsub("'", '"', delivery_by_region)) %>% rowwise() %>% do({ parsed <- fromJSON(.$delivery_by_region, flatten = TRUE) # 空数据框时仅绑定原字段,否则合并解析结果与原字段 if (nrow(parsed) == 0) { data.frame(id = .$id, spend = .$spend, impressions = .$impressions) } else { data.frame(parsed, id = .$id, spend = .$spend, impressions = .$impressions) } })
关键说明
tryCatch用于捕获JSON解析失败的情况(比如格式错误的字符串),避免代码中断;unnest的keep_empty参数控制是否保留解析后无数据的原行;- 相比
rowwise()+do(),map()+unnest()的性能更优,尤其适合处理大数据框。
内容的提问来源于stack exchange,提问作者Amol Borkar
相关产品推荐
相关产品推荐

