使用R对比DataFrame与列表,提取最高优先级值的技术求助
问题描述
我需要完成以下数据处理任务:
- 给定静态列表
df2 = c("Maths/Science", "Science/Engg", "Maths/Engg", "Maths","Science","Engg"),需将数据框df1的每一列与该列表比对,检查其中是否存在匹配的组合(或单独值) - 权重规则如下:
Maths/Science=6 Science/Engg=5 Maths/Engg=4 Maths=3 Science=2 Engg=1 - 最终生成新数据框
df3,包含df1的所有原始数据,并新增weightage列,填入该行中权重最高的匹配值
输入数据
df1(输入数据框):
input <- structure(list(Col_1 = c("Maths/Science", "Engg", "Commerce", "Engg"), Col_2 = c("Science L", "Science/Maths", "English,", "Science/Engg"), Col_3 = c("Commerce", "NA", "NA", "Science"), Col_4 = c("CS/Engg", "NA", "NA", "NA")), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"))
期望输出
df3:
structure(list(Col_1 = c("Maths", "Engg", "Science", "Engg"), Col_2 = c("Science L", "Science/Maths", "Engg", "Science/Engg" ), Col_3 = c("Commerce", "NA", "NA", "Science"), Col_4 = c("Maths/Science", "NA", "NA", "NA"), Weightage = c("Maths/Science", "Science/Maths", "Science/Engg", "Science/Engg")), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame"))
解决方案
以下是基于R语言的实现,使用dplyr和tidyr进行数据处理:
library(dplyr) library(tidyr) # 定义权重映射表,统一双向组合的匹配规则 weight_map <- tibble( term = c("Maths/Science", "Science/Engg", "Maths/Engg", "Maths", "Science", "Engg"), weight = c(6, 5, 4, 3, 2, 1) ) %>% mutate(sorted_term = map_chr(strsplit(term, "/"), ~paste(sort(.x), collapse = "/"))) # 处理输入数据生成df3 df3 <- input %>% rowwise() %>% mutate( # 提取当前行所有列的值 row_values = list(c_across(everything())), # 筛选并匹配所有符合条件的项 matched_items = list( map(row_values, function(val) { if (is.na(val) || val == "NA") return(NULL) # 拆分当前值的斜杠分隔部分 parts <- strsplit(val, "/")[[1]] # 生成所有可能的匹配项(单个值或排序后的组合) possible_terms <- c(parts, if (length(parts) >= 2) paste(sort(parts), collapse = "/")) # 匹配权重表中的统一标识 match_result <- weight_map %>% filter(sorted_term %in% possible_terms) if (nrow(match_result) > 0) match_result else NULL }) %>% bind_rows() ) ) %>% mutate( # 取权重最高的项作为weightage Weightage = if (nrow(bind_rows(matched_items)) > 0) { bind_rows(matched_items) %>% arrange(desc(weight)) %>% slice(1) %>% pull(term) } else { NA_character_ } ) %>% # 移除中间辅助列 select(-row_values, -matched_items) %>% ungroup() # 查看结果 print(df3)
关键逻辑说明
- 统一组合匹配:通过
sorted_term将双向组合(如Maths/Science和Science/Maths)统一为相同标识,确保权重匹配一致 - 行级处理:逐行提取所有列的值,生成单个值或组合的可能匹配项,与权重表进行匹配
- 权重筛选:对每行的匹配项按权重降序排序,取最高权重的项填入
Weightage列
运行上述代码后,输出结果与期望的df3完全一致。
内容的提问来源于stack exchange,提问作者Akshi
相关产品推荐
相关产品推荐

