如何将行数可变的DataFrame合并到固定25行的DataFrame中?
合并DataFrame并保留固定行数的实现方案
需求说明
- 有一个固定25行的完整DataFrame(记为
df_full),包含hc_y、hc_x、opp、oaa列; - 另一个是行数1-25的子集DataFrame(记为
df_sub),仅包含opp>0的行,列结构与完整表一致; - 需要以
hc_y和hc_x为匹配键合并:匹配到的行用子集数据,未匹配的保留完整表的原始数据,最终结果必须保持25行。
数据定义
完整DataFrame(df_full)
df_full <- structure(list( hc_y = c(250, 250, 250, 250, 250, 275, 275, 275, 275, 275, 300, 300, 300, 300, 300, 325, 325, 325, 325, 325, 350, 350, 350, 350, 350), hc_x = c(-50, -25, 0, 25, 50, -50, -25, 0, 25, 50, -50, -25, 0, 25, 50, -50, -25, 0, 25, 50, -50, -25, 0, 25, 50), opp = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), oaa = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA) ), class = "data.frame", row.names = c(NA, -25L))
子集DataFrame(df_sub)
df_sub <- structure(list( hc_x = c(-50, -50, -50, -50, -25, -25, -25, -25, -25, 0, 0, 0, 0, 25, 25, 25, 25, 50, 50, 50, 50, 50), hc_y = c(250, 300, 325, 350, 250, 275, 300, 325, 350, 250, 300, 325, 350, 250, 275, 325, 350, 250, 275, 300, 325, 350), oaa = c(0.014, 0.084, 0.053, -0.266, 0.281, 0.012, 0.018, 0.017, 0.109, -0.048, 0.017, 0.166, 0.524, -0.544, 0.163, 0.036, 0.412, -0.005, 0.033, 0.061, 1.726, 0.528), opp = c(2, 4, 2, 5, 8, 1, 1, 2, 2, 3, 2, 1, 3, 4, 3, 1, 3, 1, 2, 3, 5, 9) ), row.names = c(NA, -22L), groups = structure(list( hc_x = c(-50, -25, 0, 25, 50), .rows = structure(list(1:4, 5:9, 10:13, 14:17, 18:22), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list")) ), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", "tbl_df", "tbl", "data.frame"))
实现方法
方法1:使用dplyr包(推荐)
如果子集是分组表,先转为普通DataFrame,再通过关联+值替换完成合并:
library(dplyr) # 取消子集的分组状态(如果是分组表) df_sub <- df_sub %>% ungroup() # 合并并替换匹配到的列值 result <- df_full %>% left_join(df_sub, by = c("hc_y", "hc_x"), suffix = c("_full", "_sub")) %>% mutate( opp = coalesce(opp_sub, opp_full), oaa = coalesce(oaa_sub, oaa_full) ) %>% select(hc_y, hc_x, opp, oaa) # 恢复原列顺序
方法2:使用data.table包(高效处理大数据)
library(data.table) # 转为data.table格式 setDT(df_full) setDT(df_sub) # 匹配并直接更新对应行的值 result <- df_full[df_sub, on = .(hc_y, hc_x), `:=`(opp = i.opp, oaa = i.oaa)]
方法3:基础R实现(无需额外包)
# 合并两个表,保留完整表的所有行 merged <- merge(df_full, df_sub, by = c("hc_y", "hc_x"), all.x = TRUE, suffixes = c("_full", "_sub")) # 替换匹配到的列值 merged$opp <- ifelse(!is.na(merged$opp_sub), merged$opp_sub, merged$opp_full) merged$oaa <- ifelse(!is.na(merged$oaa_sub), merged$oaa_sub, merged$oaa_full) # 保留需要的列并恢复原顺序 result <- merged[, c("hc_y", "hc_x", "opp", "oaa")]
验证结果
执行后result将保持25行:所有在df_sub中存在的hc_y+hc_x组合会使用子集的opp和oaa值,未匹配的行则保留df_full的原始0和NA。
内容的提问来源于stack exchange,提问作者MichaelSampson123
相关产品推荐
相关产品推荐

