R中通过查找表替换数据框列值及按食品名称筛选的实现问题
R查找表匹配与查询解决方案
需求1:将food.dat中的编号重编码为对应食品名称
方法1:tidyverse生态实现(逻辑清晰,容错率高)
通过长宽表转换自动对齐类别与编号,无需手动遍历列:
# 未安装依赖先运行 install.packages("tidyverse") library(tidyverse) food.dat_named <- food.dat %>% rownames_to_column("row_id") %>% # 保留原数据行顺序 pivot_longer(-row_id, names_to = "FoodItem", values_to = "Number") %>% # 按类别+编号双字段匹配,避免不同类别同编号匹配错误 left_join(food.lookup, by = c("FoodItem", "Number")) %>% select(-Number) %>% pivot_wider(names_from = FoodItem, values_from = FoodName) %>% select(-row_id) # 移除辅助行号列
方法2:基础R实现(无需额外安装包)
逐列匹配对应类别的查找规则:
food.dat_named <- food.dat # 遍历每一列执行匹配 for (col_name in colnames(food.dat_named)) { # 提取当前列对应的查找表子集 sub_lookup <- food.lookup[food.lookup$FoodItem == col_name, ] # 按编号匹配替换名称 food.dat_named[[col_name]] <- sub_lookup$FoodName[match(food.dat_named[[col_name]], sub_lookup$Number)] }
重编码后的输出示例:
| Fruit | Vegetable | Meat | Dairy |
|---|---|---|---|
| Banana | Broccoli | Fish | IceCream |
| Mango | Broccoli | Chicken | Cheese |
| Mango | Broccoli | Fish | Yogurt |
| Apple | Broccoli | Chicken | Cheese |
| Banana | Carrot | Chicken | Yogurt |
需求2:实现食品名称查询函数
基于重编码后的数据表,实现输入指定食品名称返回所有包含该食品的行:
filter_food_row <- function(target_food, named_df = food.dat_named) { # 逐行判断是否存在目标食品 match_row <- apply(named_df, 1, function(row_vec) target_food %in% row_vec) return(named_df[match_row, ]) } # 测试示例:查询所有包含Cheese的行 filter_food_row("Cheese")
测试输出结果:
| Fruit | Vegetable | Meat | Dairy |
|---|---|---|---|
| Mango | Broccoli | Chicken | Cheese |
| Apple | Broccoli | Chicken | Cheese |
注意:如果需要直接基于原始数值表查询,可将重编码逻辑嵌入函数内,适合单次查询场景;提前生成重编码表更适合多次查询的场景,运行效率更高。
内容的提问来源于stack exchange,提问作者ksweet
相关产品推荐
相关产品推荐

