【发布时间】:2021-04-10 12:46:28
【问题描述】:
我不太确定问题标题中的术语,但我有一个包含机构非结构化地址的数据框,我想通过具有多个可能匹配项的查找表来提取他们的国家/地区。
地址可能如下所示:
address
xxx US
xxx USA yy
xxx United States yy
xxx UK
xxx United Kingdom yy
请注意,国家不一定在字符串的末尾。
管道将匹配并提取任何可能是国家/地区名称的内容(从大约 20 个国家/地区的列表中),并为每个国家/地区返回一个干净的国家/地区名称。
(df <- tribble(
~address, ~clean_country,
"xxx US", "United States",
"xxx, USA yy", "United States",
"xxx United States, yy", "United States",
"xxx UK", "United Kingdom",
"xxx United Kingdom yy", "United Kingdom",
"xxx zz yy", NA_character_,
))
我正在考虑将查找表创建为具有两列的 data.frame:
(lookup <- tribble(
~country, ~matches,
"United States", "US|USA|United States",
"United Kingdom", "UK|United Kingdom"
))
然后使用 regex 检查是否可以在
df$address 列,然后将 country 列附加为 clean_country 到 df。
当然,我对遵循其他策略的解决方案感兴趣。因为数据集比较大,所以(内存)效率更高。
【问题讨论】:
-
每个字符串值可以检测多个国家/地区吗?
-
每个地址只有一个地址,但是像“Georgia”这样的词确实是模棱两可的(美国的州和欧洲的国家)。但为简单起见,我们可以假设模棱两可不是什么大问题。我可能会在查找表中对国家/地区进行排名,并通过期望第一个匹配项更有可能是正确的猜测来获得第一个匹配项。
-
谈到效率,
US|USA|United States不是编写正则表达式的有效方法,因为您最有可能使用 NFA 正则表达式引擎(如在 stringr 正则表达式函数中)。您必须确保每个替代项在同一位置不匹配,因此U(?:SA?|nited States)是一个更有效的正则表达式。使用单词边界将使其更加精确,"\\bU(?:nited States|SA?)\\b"。 -
感谢 Wiktor,这些提示可能会在整个集合中派上用场(甚至可能避免模棱两可的匹配)