如何按规则合并2021与2020年鸟巢箱DataFrame?
鸟巢箱DataFrame合并与数据补全解决方案
首先模拟你的两个数据集(方便复现操作):
# 2021年鸟巢箱数据 df_2021 <- data.frame( box_id = c("bf1", "bf2", "rf1", "bf8", "bf9"), habitat.type = c("forest", "grassland", "wetland", NA, NA), box.material = c("wooden", "wooden", "plastic", "plastic", NA), boxes.per.post = c(1, 2, 1, NA, 3) ) # 2020年鸟巢箱数据 df_2020 <- data.frame( box_id = c("bf1", "bf2", "rf1", "rf3", "rf4", "rf6", "rf7", "bf8", "bf9"), habitat.type = c("forest", "forest", "wetland", "desert", "grassland", "urban", "mountain", "farmland", "forest"), box.material = c("wooden", "plastic", "plastic", "metal", "wooden", "plastic", "wooden", "plastic", "wooden"), boxes.per.post = c(1, 2, 1, 2, 1, 1, 3, 2, 3), box.age = c(3, 2, 4, 1, 2, 1, 3, 2, 4), land.water = c("land", "land", "water", "land", "land", "land", "land", "land", "land") )
分步实现需求
使用dplyr包完成所有操作,逻辑清晰且贴合需求:
1. 全连接保留所有箱号
用full_join基于box_id连接两个数据集,既能保留2021年已有箱号,也能引入2020年独有的rf3、rf4、rf6、rf7:
library(dplyr) combined_df <- full_join(df_2021, df_2020, by = "box_id", suffix = c("_2021", "_2020"))
2. 处理共享字段:优先保留2021年数据,缺失值用2020年补全
对每个共享字段,用coalesce函数优先取2021年的值,仅当2021年为NA时才用2020年的数据填充,同时自动处理字段值冲突(比如bf2的box.material会保留2021年的"wooden"):
combined_df <- combined_df %>% mutate( habitat.type = coalesce(habitat.type_2021, habitat.type_2020), box.material = coalesce(box.material_2021, box.material_2020), boxes.per.post = coalesce(boxes.per.post_2021, boxes.per.post_2020) ) %>% # 移除临时生成的年份后缀列 select(-ends_with("_2021"), -ends_with("_2020"))
3. 保留2020年独有列
box.age和land.water已经通过全连接带入数据集,无需额外操作,直接保留即可。
最终结果验证
执行print(combined_df)会得到符合预期的输出:
box_id habitat.type box.material boxes.per.post box.age land.water 1 bf1 forest wooden 1 3 land 2 bf2 grassland wooden 2 2 land 3 rf1 wetland plastic 1 4 water 4 bf8 farmland plastic 2 2 land 5 bf9 forest wooden 3 4 land 6 rf3 desert metal 2 1 land 7 rf4 grassland wooden 1 2 land 8 rf6 urban plastic 1 1 land 9 rf7 mountain wooden 3 3 land
你之前尝试方法的问题说明
cbind:仅按列拼接,不匹配box_id,会导致数据完全错位,不适用此类关联数据合并。left_join:仅保留2021年的箱号,无法引入2020年独有的箱号。- 默认
merge:等同于inner_join,只保留两个数据集共有的箱号,丢失目标数据。 - 未处理冲突的
full_join:会生成重复的年份后缀列,无法自动优先保留2021年的数据。
内容的提问来源于stack exchange,提问作者blake.struthers
相关产品推荐
相关产品推荐

