通过匹配因子级别合并数据框,将匹配的因子级别添加为新列
解决方法:将匹配的多值列拆分为多列并合并
要实现你的需求,核心是先把df2中每个lepsp对应的多个plntsp转换为宽格式(每个plntsp作为单独列),再和df1合并。下面分步骤给出具体实现:
1. 先重现你的数据(方便验证)
set.seed(571) year = as.factor(c(rep("1998", 20), rep("1999", 16))) lepsp = c(letters[1:20], c('a','b','c'),letters[8:20]) freq = rpois(36, lambda=12) df1 <- data.frame(year, lepsp, freq) lepsp = c(letters[1:26],c('a','b','c'),letters[1:20],c('e','f',"h")) plntsp = c(paste("plnt", sep= "_", letters[1:26]), paste("plnt",sep="_",letters[1:20]), paste("plnt",sep="_",letters[18:23])) df2 <- data.frame(lepsp, plntsp)
2. 使用tidyverse工具实现(推荐,代码更直观)
我们用dplyr做分组编号,tidyr转宽格式,最后合并:
library(dplyr) library(tidyr) # 第一步:给每个lepsp对应的plntsp添加序号(生成plntsp1、plntsp2...的列名) df2_processed <- df2 %>% group_by(lepsp) %>% mutate(plntsp_col = paste0("plntsp", row_number())) %>% ungroup() # 第二步:将df2转成宽格式,无匹配值的位置用NA填充 df2_wide <- df2_processed %>% pivot_wider(names_from = plntsp_col, values_from = plntsp, values_fill = NA) # 第三步:和df1合并,保留df1所有行,并将NA替换为空字符串 df_result <- df1 %>% left_join(df2_wide, by = "lepsp") %>% mutate(across(starts_with("plntsp"), ~replace_na(.x, "")))
查看结果示例:
# 查看前6行结果 head(df_result)
3. 用Base R实现(无需额外包)
如果不想加载tidyverse包,也可以用基础R函数完成:
# 给每个lepsp的plntsp添加序号 df2$plntsp_col <- ave(rep(1, nrow(df2)), df2$lepsp, FUN = seq_along) df2$plntsp_col <- paste0("plntsp", df2$plntsp_col) # 转成宽格式 df2_wide_base <- reshape(df2, idvar = "lepsp", timevar = "plntsp_col", direction = "wide") # 清理列名(去掉默认的plntsp.前缀) colnames(df2_wide_base) <- gsub("plntsp\\.", "", colnames(df2_wide_base)) # 合并df1和处理后的df2,替换NA为空字符串 df_result_base <- merge(df1, df2_wide_base, by = "lepsp", all.x = TRUE) df_result_base[is.na(df_result_base)] <- ""
为什么你的原代码无法实现?
你之前用df1$plntsp<-df2$plntsp[match(df1$lepsp, df2$lepsp)]只能拿到每个lepsp在df2中第一个匹配的plntsp,但df2中同一个lepsp可能对应多个plntsp,所以必须先把多值转换为多列的宽格式,再合并才能满足需求。
内容的提问来源于stack exchange,提问作者Danielle
相关产品推荐
相关产品推荐

