按站点统计两个Dataframe间的物种匹配数量
解决方案
两种方法都可以实现按站点统计两表共同物种数量,以下是具体代码:
方法一:内连接 + 分组计数
这是最直接的方式,利用内连接筛选出两表共有的Site-Species组合,再按站点统计数量:
library(dplyr) # 清理数据:保留关键列并确保每个Site-Species唯一 df1_clean <- df1 %>% select(Site, Species) %>% distinct() df2_clean <- df2 %>% select(Site, Species) %>% distinct() # 统计每个站点的共同物种数 common_species_count <- df1_clean %>% inner_join(df2_clean, by = c("Site", "Species")) %>% count(Site, name = "common_species_number") # 查看结果 print(common_species_count)
针对你提供的BRY1示例,运行后会得到Site = BRY1, common_species_number = 1,符合预期。
方法二:分组拆分 + 交集计算
如果需要更灵活的站点级操作,可以拆分数据后逐个计算物种交集:
library(dplyr) library(purrr) # 按站点拆分数据(仅保留关键列) df1_split <- df1 %>% select(Site, Species) %>% distinct() %>% group_split(Site) df2_split <- df2 %>% select(Site, Species) %>% distinct() %>% group_split(Site) # 遍历每个站点,计算共同物种数量 common_counts <- map2_df(df1_split, df2_split, function(x, y) { tibble( Site = first(x$Site), common_species_number = length(intersect(x$Species, y$Species)) ) }) # 查看结果 print(common_counts)
关于semi_join的问题
你之前用semi_join效果不佳,大概率是因为只完成了筛选步骤,没有后续的分组计数。如果要用semi_join,可以这样补充:
semi_join(df1, df2, by = c("Site", "Species")) %>% select(Site, Species) %>% distinct() %>% count(Site, name = "common_species_number")
不过本质上和方法一逻辑一致,只是筛选方式不同。
内容的提问来源于stack exchange,提问作者WormWarbler
相关产品推荐
相关产品推荐

