如何在R语言中从数据集的affiliation列提取城市?
从 affiliation 列提取最后一个城市名到新列的解决方案
我明白你想要从db$affiliation里提取每行最后一个出现的城市名称,放到新列db$cities里,没找到匹配城市就返回NA。之前的尝试没成功主要是因为只检查了拆分后的第一列,而且没有从后往前匹配城市列表。下面是具体的修正方案:
步骤1:加载所需包和城市数据
首先确保你安装了需要的包,然后加载它们和世界城市数据集:
# 安装依赖包(如果未安装过) install.packages(c("maps", "splitstackshape", "dplyr")) # 加载包 library(maps) library(splitstackshape) library(dplyr) # 加载世界城市数据,并转成大写(匹配你的affiliation列的大写格式) data(world.cities) city_list <- toupper(world.cities$name)
步骤2:预处理affiliation列
先移除括号内的作者信息,再按逗号拆分内容:
# 移除方括号及内部的作者信息 db$affiliation_clean <- gsub("\\[[^\\]]*\\]", "", db$affiliation, perl = TRUE) # 按", "拆分字符串到多列 db_split <- cSplit(db, "affiliation_clean", sep = ", ", type.convert = FALSE)
步骤3:定义函数提取最后一个匹配的城市
这个函数会接收每行拆分后的内容,从后往前找第一个出现在世界城市列表里的元素:
get_last_city <- function(row_elements) { # 把行内容转成字符向量,去掉空值 elements <- na.omit(as.character(row_elements)) # 检查每个元素是否在城市列表里 is_city <- elements %in% city_list # 如果有匹配的,返回最后一个(也就是从后往前第一个);否则返回NA if (any(is_city)) { return(elements[max(which(is_city))]) } else { return(NA_character_) } }
步骤4:应用函数到所有行
提取拆分后的所有相关列,对每行应用函数得到cities列:
# 筛选出所有拆分后的affiliation_clean_开头的列 city_columns <- grep("^affiliation_clean_", names(db_split), value = TRUE) # 对每行应用函数,生成cities列 db$cities <- apply(db_split[, city_columns], 1, get_last_city)
关于你之前尝试的问题说明
你之前只检查了affiliation_1列,但城市往往出现在后面的列(比如你的第一个示例里城市在第3列,第三个示例也在第3列)。另外你的第二个示例里,TWENTE是大学名称,不是城市,实际对应的城市是ENSCHEDE,这个会被正确提取出来。
内容的提问来源于stack exchange,提问作者Marco C
相关产品推荐
相关产品推荐

