R语言:按物种匹配将df1每行对应减去df2同物种行
在R中按物种匹配计算个体元素值与物种均值的差值
我有两个数据框:
- df1(15行,1080列):包含个体ID、物种信息及大量元素数值列,示例如下:
df1 <- data.frame( individuals = c("POR20_02", "POR20-03", "POR20-04"), species = c("dia", "het", "hyb"), element1 = c(0.003, 0.005, 0.002), element2 = c(0.005, 0.009, 0.007), element3 = c(0.001, 0.002, 0.005) )
- df2(3行,1079列):是df1按物种分组计算的各元素均值,无个体ID列,示例如下:
df2 <- data.frame( species = c("dia", "hyb", "het"), element1 = c(0.004, 0.007, 0.004), element2 = c(0.006, 0.006, 0.005), element3 = c(0.002, 0.003, 0.006) )
需求:按物种匹配,将df1中每行的所有元素列数值减去df2对应物种行的同列均值,得到每个个体相对于物种均值的差值。
方法1:使用dplyr + tidyr(简洁易读)
library(tidyverse) # 给df2的均值列添加后缀,避免合并后列名重复 df2_renamed <- df2 %>% rename_with(~paste0(., "_mean"), -species) # 匹配均值并计算差值 result_df <- df1 %>% left_join(df2_renamed, by = "species") %>% # 对所有element列计算差值,生成带_diff后缀的新列 mutate(across(starts_with("element"), ~ .x - get(paste0(cur_column(), "_mean")), .names = "{.col}_diff")) %>% # 可选:移除均值列,只保留原始列和差值列 select(-ends_with("_mean"))
方法2:使用base R(无需额外包)
# 获取所有元素列的列名 element_cols <- setdiff(colnames(df1), c("individuals", "species")) # 匹配每个个体对应的物种均值行 mean_rows <- df2[match(df1$species, df2$species), element_cols] # 计算所有元素列的差值 diff_values <- df1[element_cols] - mean_rows # 合并个体信息与差值结果,也可保留原始元素列 result_df <- cbind(df1[c("individuals", "species")], diff_values) # 若要保留原始列并添加差值列,可修改列名后合并: # colnames(diff_values) <- paste0(element_cols, "_diff") # result_df <- cbind(df1, diff_values)
注意事项
- 确保df1和df2的物种名称完全一致(大小写、特殊符号均需匹配),否则会出现匹配失败的NA值
- 两个数据框的元素列名必须完全对应,否则减法操作会出错
内容的提问来源于stack exchange,提问作者Alex-James Roussel
相关产品推荐
相关产品推荐

