R语言基于自定义映射数据框拆分tibble的Spray列为f、s两列
双向映射匹配的tidyverse实现方案
核心逻辑
- 常规左连接仅能实现单向匹配,但需求中
Spray列的取值既可能出现在fs映射表的f列,也可能出现在fs表的s列,无法通过单次join完成匹配 - 实现思路:将fs映射表转换为双向可识别的查找结构,把每一组(f值, s值)的配对拆分为两个匹配入口:分别以f值、s值为匹配键,保留对应的完整配对关系,再和原表按Spray值左连接即可
- 查找表构造过程中通过
distinct去重,可兼容fs表中s列存在重复值的场景(比如本例中F5、F6对应的s值都是dsf),避免匹配冲突
完整可运行代码
library(tidyverse) # 构造原始tibble数据 tib <- tibble( Dis = c("One", "One", "Two", "Three", "Three"), Spray = c("F1", "F1", "F2", "other", "nj"), freq = c(80, 20, 1.34, 15.3, 20.2), Nom = c("A", "B", "C", "C", "D") ) # 构造存储映射关系的fs数据框 f_vec <- c("F1", "F2", "F3", "F4", "F5", "F6", "F7") s_vec <- c("other", "nj", "na", "ker", "dsf", "dsf", "rth") fs <- data.frame(f = f_vec, s = s_vec) # 构建双向可匹配的查找表 fs_lookup <- fs %>% # 提取f值作为匹配键的条目 transmute(match_key = f, f, s) %>% # 提取s值作为匹配键的条目 bind_rows(fs %>% transmute(match_key = s, f, s)) %>% # 去重避免匹配冗余 distinct(match_key, .keep_all = TRUE) # 左连接匹配,保留原表所有行和顺序 result <- tib %>% left_join(fs_lookup, by = c("Spray" = "match_key"))
结果校验
运行代码后输出的result表完全符合映射逻辑:
| Dis | Spray | freq | Nom | f | s |
|---|---|---|---|---|---|
| One | F1 | 80 | A | F1 | other |
| One | F1 | 20 | B | F1 | other |
| Two | F2 | 1.34 | C | F2 | nj |
| Three | other | 15.3 | C | F1 | other |
| Three | nj | 20.2 | D | F2 | nj |
注:对照给出的预期结果,第5行的s值写为
other,结合fs表中F2与nj的固定配对关系,该位置应为nj,属于书写笔误。
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

