在R语言中分类:为向量元素匹配数据框中的对应类别
解决方法:宽表转长表 + 构建值-类别映射
这其实是个典型的宽格式数据转长格式+值到类别映射的问题,咱们一步步来实现你要的效果:
第一步:先把你的原始数据框整理成可操作的结构
根据你给出的结构,首先我们需要把这个每行对应类别+多个取值的宽表,转换成每行只有「类别-单个取值」配对的长表——这是后续匹配的关键,因为宽格式没办法直接做一对一的映射。
先构造你的原始数据框:
# 按照你给出的结构创建宽表 df <- data.frame( category = c("car", "food", "shoe"), item1 = c("Chevy", "Ritz", "Nike"), item2 = c("Honda", "Hershey", "UA"), item3 = c("Toyota", "Nestle", "Reebok") )
第二步:把宽表转成长表
用tidyr包的pivot_longer函数来转换,这样每个取值都会和它所属的类别一一对应:
library(tidyr) # 转成长格式,只保留类别和取值两列 long_df <- df %>% pivot_longer( cols = starts_with("item"), # 选中所有以item开头的列(也就是所有取值列) names_to = NULL, # 不需要保留原来的列名(item1/item2这类) values_to = "value" # 把取值列合并成一列,命名为value )
转换后的long_df核心结构是这样的:
| category | value |
|---|---|
| car | Chevy |
| car | Honda |
| car | Toyota |
| food | Ritz |
| food | Nestle |
| shoe | UA |
| shoe | Reebok |
第三步:构建映射并匹配你的输入向量
现在我们可以用两种简单的方法来得到结果:
方法一:用命名向量直接索引
先创建一个「取值为名字,类别为值」的命名向量,然后直接用输入向量索引就能得到对应类别:
# 创建值到类别的映射向量 category_map <- setNames(long_df$category, long_df$value) # 你的输入向量 input_vec <- c("Toyota", "UA", "Reebok", "Nestle") # 直接索引得到结果 result <- category_map[input_vec]
运行后result就是你要的:
Toyota UA Reebok Nestle "car" "shoe" "shoe" "food"
方法二:用match函数匹配
如果你不想用命名向量,也可以用match函数找到每个输入值在长表中的位置,再提取对应类别:
result <- long_df$category[match(input_vec, long_df$value)]
得到的结果和上面完全一致。
注意点
如果你的数据中存在同一个取值属于多个类别的情况,match和命名向量都会返回第一个匹配到的类别,如果你需要处理这种多匹配的情况,可以用dplyr的筛选功能获取所有对应类别:
library(dplyr) input_value <- "UA" all_categories <- long_df %>% filter(value == input_value) %>% pull(category)
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

