R中解析地址字段遭遇lexical error的解决方法求助
解析R数据框中的Address_Parse字段并转为结构化列
数据背景
现有R数据框my_file,结构定义如下:
my_file = structure(list(NAME = c("name1", "name2"), Address_Parse = c("[('372', 'StreetNumber'), ('river', 'StreetName'), ('St', 'StreetType'), ('S', 'StreetDirection'), ('toronto', 'Municipality'), ('ON', 'Province'), ('A1C', 'PostalCode'), ('9R7', 'PostalCode')]", "[('208', 'StreetNumber'), ('ocean', 'StreetName'), ('St', 'StreetType'), ('E', 'StreetDirection'), ('Toronto', 'Municipality'), ('ON', 'Province'), ('J8N', 'PostalCode'), ('1G8', 'PostalCode')]" )), class = "data.frame", row.names = c(NA, -2L))
打印后显示为:
NAME Address_Parse 1 name1 [('372', 'StreetNumber'), ('river', 'StreetName'), ('St', 'StreetType'), ('S', 'StreetDirection'), ('toronto', 'Municipality'), ('ON', 'Province'), ('A1C', 'PostalCode'), ('9R7', 'PostalCode')] 2 name2 [('208', 'StreetNumber'), ('ocean', 'StreetName'), ('St', 'StreetType'), ('E', 'StreetDirection'), ('Toronto', 'Municipality'), ('ON', 'Province'), ('J8N', 'PostalCode'), ('1G8', 'PostalCode')]
需求目标
将Address_Parse列中的各类地址元素(StreetNumber、StreetName等)提取为独立列,合并重复的PostalCode值,最终得到如下结果:
name StreetNumber StreetName StreetType StreetDirection Municipality Province PostalCode 1 name1 372 river St S toronto ON A1C9R7 2 name2 208 ocean St E Toronto ON J8N1G8
错误尝试及问题原因
最初误以为Address_Parse是JSON格式,使用jsonlite包解析时出现语法错误:
library(dplyr) library(tidyr) library(purrr) library(jsonlite) final = my_file %>% mutate( json_parsed = map(Address_Parse, ~ fromJSON(., flatten=TRUE)) ) %>% unnest(json_parsed)
错误信息:
Error in `mutate()`: ! Problem while computing `json_parsed = map(Address_Parse, ~fromJSON(., flatten = TRUE))`. Caused by error: ! lexical error: invalid char in json text. [('372', 'StreetNumber'), ('rive (right here) ------^ Run `rlang::last_error()` to see where the error occurred.
改用rowwise()+do()的方式仍报相同错误。问题核心:该字段不是标准JSON——JSON使用双引号,且键值对格式不同,这里是类似Python元组的字符串结构。
解决方案
通过以下步骤处理:
- 将字符串中的单引号替换为双引号,把元组格式转为符合JSON语法的数组;
- 解析处理后的字符串为嵌套列表;
- 把列表转为数据框,合并重复的PostalCode值;
- 与原数据框的NAME列合并。
完整代码
library(dplyr) library(purrr) library(jsonlite) # 处理字符串并解析 result <- my_file %>% mutate( # 替换单引号为双引号,适配JSON语法 addr_clean = gsub("'", "\"", Address_Parse), # 解析为嵌套列表 addr_list = map(addr_clean, fromJSON), # 转换为数据框并合并重复的PostalCode addr_df = map(addr_list, function(x) { # 转置数组并设置列名 df <- as.data.frame(t(x[,1]), stringsAsFactors = FALSE) colnames(df) <- x[,2] # 合并多个PostalCode值 if("PostalCode" %in% colnames(df)) { df$PostalCode <- paste(df$PostalCode, collapse = "") } df }) ) %>% # 展开嵌套数据框 unnest(addr_df) %>% # 调整列名和顺序 select(name = NAME, StreetNumber, StreetName, StreetType, StreetDirection, Municipality, Province, PostalCode) print(result)
代码说明
gsub("'", "\"", Address_Parse):把单引号替换为双引号,让字符串满足JSON解析要求;map(addr_clean, fromJSON):将处理后的字符串解析为嵌套列表;- 自定义函数处理每个地址列表:转置数组后设置列名,合并同一行的多个PostalCode值;
unnest(addr_df):展开嵌套数据框,最终得到目标结构化数据。
运行后输出与需求目标一致。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

