基于行与列匹配将小DataFrame合并至指定大DataFrame
解决方案:将多个小DataFrame匹配填入大模板并替换空值为0
基础R实现(无需额外包)
这种方法适合刚接触R的用户,逻辑清晰且不需要安装额外工具包:
# 定义模板数据框 formattable <- data.frame( "Agriculture" = rep(NA, 8), "Mining" = rep(NA, 8), "Industry" = rep(NA, 8), "Services" = rep(NA, 8), "Households" = rep(NA, 8), row.names = c("N01 water","N02 solar", "P01 coal", "P02 natural gas", "P03 diesel", "R01 waste", "R02 residuals","R03 losses" ) ) # 定义小数据框 data1 <- data.frame( "Agriculture" = c(5,7,NA), "Mining" = c(5,6,NA), "Services" = c(4,8,NA), "Households" = c(1,11,NA), row.names = c("P01 coal", "P02 natural gas", "P03 diesel") ) data2 <- data.frame( "Agriculture" = c(3,2), "Mining" = c(NA,5), "Services" = c(5,7), row.names = c("N01 water","N02 solar") ) data3 <- data.frame( "Agriculture" = c(3,6,5), "Mining" = c(NA,0,5), "Industry" = c(5,NA,NA), "Services" = c(NA,NA,NA), "Households" = c(7,8,9), row.names = c("R01 waste", "R02 residuals","R03 losses" ) ) # 将所有小数据框存入列表,批量处理 df_list <- list(data1, data2, data3) # 遍历列表,将小数据框的内容匹配填入模板 for(df in df_list) { # 筛选出模板中存在的行和列 matched_rows <- intersect(rownames(df), rownames(formattable)) matched_cols <- intersect(colnames(df), colnames(formattable)) # 填充对应位置的数据 formattable[matched_rows, matched_cols] <- df[matched_rows, matched_cols] } # 将所有空值替换为0 formattable[is.na(formattable)] <- 0 # 查看最终结果 print(formattable)
代码逻辑说明:
- 把小DataFrame放进列表,避免重复编写填充代码
- 通过
intersect()精准匹配行名和列名,确保数据只填入模板的对应位置,不会改变模板原有维度 - 最后用
is.na()定位所有空值,统一替换为0
Tidyverse实现(适合熟悉管道操作的用户)
如果习惯使用dplyr和purrr等tidyverse工具,可以用更简洁的管道式代码:
library(tidyverse) # 定义模板和小数据框(代码同基础R部分,此处省略) # 将模板转换为带行名列的长格式 formattable_tidy <- formattable %>% rownames_to_column(var = "category") # 把所有小数据框转换为长格式并合并 combined_data <- map_dfr(df_list, ~ .x %>% rownames_to_column(var = "category")) # 合并数据、填充空值并转回宽格式 result <- formattable_tidy %>% left_join(combined_data, by = "category") %>% # 用小数据框的值覆盖模板的空值 mutate(across(-category, ~ ifelse(is.na(.y), .x, .y))) %>% # 清理列名并替换剩余空值为0 select(-ends_with(".x")) %>% rename_with(~ str_remove(.x, "\\.y")) %>% mutate(across(-category, ~ replace_na(.x, 0))) %>% column_to_rownames(var = "category") print(result)
代码逻辑说明:
- 转换为长格式(tidy格式)后,用
left_join保证保留模板的所有行和列 - 通过
mutate和replace_na批量处理空值,最后转回原始的宽格式
内容的提问来源于stack exchange,提问作者Red_24
相关产品推荐
相关产品推荐

