You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用dplyr合并含不同时间观测的两个R数据框?

解决方案(基于dplyr/tidyr)

首先加载所需工具包:

library(tidyverse)

先定义原始数据(与你提供的内容一致):

row11 <- c("a", "c", "2000", "2001", "2005")
row12 <- c("", "", 7, 10, 15)
f1 <- as.data.frame(rbind(row11, row12))

row21 <- c("a", "b", "c", "2002", "2005")
row22 <- c("", "", "", 1, 15)
f2 <- as.data.frame(rbind(row21, row22)) 

单个数据框的处理函数

编写通用函数统一处理f1和f2,将其转换为目标格式的单行数据:

process_df <- function(df) {
  # 提取第一行作为列名,第二行作为有效数据行
  colnames(df) <- df[1, ]
  df_data <- df[-1, ] %>% mutate(across(everything(), as.character))
  
  # 分离分类列(a、b、c)与年份列
  cat_cols <- c("a", "b", "c")
  year_cols <- setdiff(colnames(df_data), cat_cols)
  
  # 转换为长格式,统一处理年份和对应数值
  df_long <- df_data %>%
    pivot_longer(cols = all_of(year_cols), names_to = "year", values_to = "value") %>%
    mutate(year = as.integer(year),
           value = ifelse(value == "", NA, as.numeric(value)))
  
  # 补全2000-2005所有年份,再转回宽格式,同时补全缺失的分类列
  df_wide <- df_long %>%
    complete(year = 2000:2005) %>%
    pivot_wider(names_from = year, values_from = value) %>%
    mutate(across(all_of(cat_cols), ~ ifelse(is.na(.), "", .)))
  
  return(df_wide)
}

合并处理结果

分别处理两个数据框后,合并得到最终的f3:

f1_processed <- process_df(f1)
f2_processed <- process_df(f2)

f3 <- bind_rows(f1_processed, f2_processed)
# 调整列顺序:先分类列a、b、c,再按年份顺序排列2000-2005
f3 <- f3 %>% select(all_of(c("a", "b", "c")), as.character(2000:2005))

查看最终结果:

print(f3)
# 输出与预期一致:
#   a b c 2000 2001 2002 2003 2004 2005
# 1 "" "" ""    7   10   NA   NA   NA    15
# 2 "" "" ""   NA   NA    1   NA   NA    15

说明

  • 通用函数process_df避免重复代码,统一处理逻辑
  • 用complete补全所有目标年份,缺失值自动填充NA
  • 通过pivot_longer和pivot_wider完成长/宽格式转换,是tidyverse处理此类结构调整的标准流程

内容的提问来源于stack exchange,提问作者MPB_2022

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 23:57:18