如何在R中匹配数据框元素与另一数据框的组/超组
R数据框组匹配实现方法
构造基础数据框
组映射数据框data
library(tibble) Groups = c("animals","furniture","vehicles","House", "Commute","Food","Need","Family") elements = c("cat,dog,bird", "chair,table", "car,motorcycle", "animals,furniture", "bike,rollers", "pasta,pizza", "water,power", "House,Mother") p = seq(1,8,1) data = tibble(Groups, elements, p)
该数据框定义了组与超组的嵌套关系,例如Family包含House和Mother,House包含animals和furniture。
样本数据框df
date = c(rep(as.Date("2022/1/1"),3), rep(as.Date("2022/1/2"),3), rep(as.Date("2022/1/3"),3)) var1 = c(rep("cat",3), rep("cat,Mother,bike,pasta",3), rep("dog,bird",3)) df = tibble(date, var1)
匹配需求
为df添加Groups列,需遵循以下规则:
- 当
var1的所有元素完全属于某个组/超组时,匹配最高层级的组(例如2022-01-02的cat,Mother,bike,pasta对应Family) - 若仅单个元素且无对应完整组,填充
NA(例如2022-01-01的cat) - 若元素组完全匹配某个基础组,对应该组(例如2022-01-03的
dog,bird对应animals)
实现步骤与代码
步骤1:预处理组数据,构建层级映射
先展开组的嵌套关系,明确每个组包含的所有底层元素,并确定组的层级(超组层级更高):
library(dplyr) library(tidyr) # 拆分elements为列表,方便后续处理 data_processed <- data %>% mutate(elements_list = strsplit(elements, ",")) # 递归获取某个组包含的所有底层元素(非组的元素) get_all_elements <- function(group_name) { current_elements <- data_processed %>% filter(Groups == group_name) %>% pull(elements_list) %>% unlist() # 判断元素是否为组 is_group <- current_elements %in% data_processed$Groups if (any(is_group)) { # 递归处理子组,合并结果 sub_elements <- lapply(current_elements[is_group], get_all_elements) %>% unlist() c(current_elements[!is_group], sub_elements) } else { current_elements } } # 为每个组生成完整的底层元素集合,并按层级降序排序 group_full_elements <- data_processed %>% rowwise() %>% mutate(full_elements = list(unique(get_all_elements(Groups)))) %>% ungroup() %>% mutate(level = sapply(full_elements, length)) %>% arrange(desc(level))
步骤2:处理样本数据,拆分元素
将df中的var1拆分为元素列表:
df_processed <- df %>% mutate(var1_elements = strsplit(var1, ","))
步骤3:实现匹配逻辑
遍历每个样本的元素集合,找到所有完全包含该集合的组,选择层级最高的组;无匹配则返回NA:
match_group <- function(elements) { # 筛选出所有包含当前元素集合的组 matched_groups <- group_full_elements %>% filter(sapply(full_elements, function(x) all(elements %in% x))) if (nrow(matched_groups) == 0) { NA_character_ } else { # 返回层级最高的组(已按层级降序,取第一个) matched_groups$Groups[1] } } # 应用匹配函数,生成结果 df_result <- df_processed %>% rowwise() %>% mutate(Groups = match_group(var1_elements)) %>% ungroup() %>% select(date, var1, Groups)
最终结果
运行后df_result输出如下:
# A tibble: 9 × 3 date var1 Groups <date> <chr> <chr> 1 2022-01-01 cat NA 2 2022-01-01 cat NA 3 2022-01-01 cat NA 4 2022-01-02 cat,Mother,bike,pasta Family 5 2022-01-02 cat,Mother,bike,pasta Family 6 2022-01-02 cat,Mother,bike,pasta Family 7 2022-01-03 dog,bird animals 8 2022-01-03 dog,bird animals 9 2022-01-03 dog,bird animals
内容的提问来源于stack exchange,提问作者Homer Jay Simpson
相关产品推荐
相关产品推荐

