如何在grep未匹配内容时自动生成含NA的行?
问题描述
从50份结构一致的Word文档表格中提取数据构建数据框,表格为2列(Name、Values)共60行,但源数据不可编辑,df$Name列存在书写错误或整行缺失。需要合并数据后转置,让Name作为表头、Value作为行数据。
目前用grep基于关键词提取目标行,但如果某个预设的Name值(比如"Trays Code")缺失,不会生成对应行,需要自动生成该行:Name为预设值、Value为NA,且保持原有顺序。曾尝试用dplyr连接标准列名表,但因df$Name和标准名称Col存在差异导致重复项,不确定是否要用循环处理,担心逻辑复杂。
预设的标准Name列表和当前使用的匹配关键词如下:
Col <- c("Top Film / Web code (if applicable)", "Base Film / Web code (if applicable)", "Top Label / Sleeves code", "Base Label code", "Promotional Label code", "Trays Code", "SRP code", "SRP label code", "Packing format (overwrap, MAP, VAC)", "Vac pressure (if applicable)", "Die set", "Optimal running speed (max)", "Gas mix (if applicable)", "Pressure for Leaker checks (bar)", "Frequency of checks", "Metal Detection Limits", "No. of Units per pack","Pack weight", "Claims", "Shelf Life Of Product From Pack / Slice", "Date code format", "Health Mark", "UK & EU Address","“e” mark present", "Weight present", "Top Label Placement", "Base Label Placement", "Promo Label Placement", "Barcode (if applicable)", "No. of Packs per SRP/Basket","Weight of outercase", "Max No. of SRP/Baskets per pallet") toMatch <- c("Top Film","Base Film", "Top Label", "Base Label", "Promotional", "Trays", "SRP","Packing format", "Vac pressure", "Die set", "Optimal running speed", "Gas mix", "Pressure", "Frequency", "Metal Detection Limits", "per pack", "Pack weight", "Claims", "Shelf Life", "Date code", "Health", "Address", "“e”", "Weight present", "Top Label Place", "Base Label Place", "Promo Label Place", "Barcode","No. of Packs","outercase", "Max No.") tab_select <- unique(df[grep(paste(toMatch,collapse="|"), df$Name, ignore.case=TRUE),])
解决方案
方法1:用dplyr+fuzzyjoin做模糊匹配后补全
fuzzyjoin可处理名称的模糊匹配,避免直接连接导致的重复,再和标准Col列表做左连接补全NA行:
- 把标准
Col转成数据框:
library(dplyr) library(fuzzyjoin) standard_df <- tibble(Name = Col)
- 用
regex_left_join做模糊匹配,处理重复项:
matched_df <- regex_left_join(tab_select, standard_df, by = c(Name = "Name"), ignore_case = TRUE) %>% group_by(Name.y) %>% summarize(Values = first(Values)) %>% ungroup() %>% rename(Name = Name.y)
- 左连接标准表补全缺失行:
final_df <- standard_df %>% left_join(matched_df, by = "Name")
方法2:循环匹配每个标准Name手动补全
无需额外包,针对每个标准Name单独匹配,未匹配到则生成NA行:
final_list <- list() for (target_name in Col) { match_idx <- grep(target_name, df$Name, ignore.case = TRUE) if (length(match_idx) > 0) { value <- unique(df$Values[match_idx]) final_list[[target_name]] <- ifelse(length(value) > 0, value[1], NA) } else { final_list[[target_name]] <- NA } } final_df <- tibble(Name = names(final_list), Values = unlist(final_list))
优化建议:建立匹配关键词与标准Name的映射
避免一个关键词匹配多个标准Name的问题,提前指定专属匹配规则:
match_map <- tibble( Name = Col, Keyword = c("Top Film / Web code", "Base Film / Web code", "Top Label / Sleeves code", "Base Label code", "Promotional Label code", "Trays Code", "SRP code", "SRP label code", "Packing format", "Vac pressure", "Die set", "Optimal running speed", "Gas mix", "Pressure for Leaker checks", "Frequency of checks", "Metal Detection Limits", "No. of Units per pack", "Pack weight", "Claims", "Shelf Life", "Date code format", "Health Mark", "UK & EU Address", "“e” mark present", "Weight present", "Top Label Placement", "Base Label Placement", "Promo Label Placement", "Barcode", "No. of Packs per SRP/Basket", "Weight of outercase", "Max No. of SRP/Baskets per pallet") )
后续匹配时基于该映射精准对应,减少重复匹配。
内容的提问来源于stack exchange,提问作者SFrazer
相关产品推荐
相关产品推荐

