如何基于含多值的dfcheck为dfdata匹配新增status与stock列?
实现方案
步骤1:预处理参考数据框,建立名称映射关系
首先需要把dfcheck中用分号分隔的name值拆分为独立条目,构建每个名称与status、stock的一对一映射表:
# 若未安装tidyr包,先执行 install.packages("tidyr") library(tidyr) # 拆分name列,生成每行对应单个名称的映射表 dfcheck_map <- dfcheck %>% separate_rows(name, sep = ";") %>% mutate(name = trimws(name)) # 去除名称可能带的空格(示例中无空格,可按需保留)
步骤2:遍历匹配并生成目标列
遍历dfdata中除id外的所有列,为每个列匹配对应的status和stock,并合并到原数据框:
# 获取需要处理的标题列(排除id列) title_columns <- setdiff(colnames(dfdata), "id") # 循环处理每个标题列 for(col in title_columns) { # 提取列序号,用于命名新的status和stock列 col_index <- sub("title", "", col) # 匹配当前列的名称,获取对应状态和库存信息 match_result <- dfdata %>% select(id, all_of(col)) %>% left_join(dfcheck_map, by = setNames("name", col)) %>% select(id, status, stock) %>% rename_with(~paste0(.x, col_index), c(status, stock)) # 将匹配结果合并到原数据框 dfdata <- dfdata %>% left_join(match_result, by = "id") }
最终结果
运行上述代码后,dfdata将生成预期输出:
print(dfdata) # id title1 title2 status1 stock1 status2 stock2 # 1 id1 amazon1 yahoo2 open/close company energy open other # 2 id2 google1 <NA> open/close company energy <NA> <NA> # 3 id3 yahoo1 amazon2 close goods and books open other
逻辑说明
- 拆分映射表:用
separate_rows把多值的name拆分为单行,解决原数据中一个status对应多个名称的一对多匹配问题。 - 列匹配与合并:通过
left_join保留原数据的NA值(如id2的title2为空时,对应状态和库存也为空),并重命名匹配结果列,确保列名与原标题列一一对应。
内容的提问来源于stack exchange,提问作者Erik Brole
相关产品推荐
相关产品推荐

