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

R语言:无for循环重格式化并合并多份宽格式气候数据框

问题描述

我有4份宽格式的气候数据框,结构为第一列为年份(Year),第2至13列分别对应1-12月的气候变量均值。需要将它们转换合并为长格式数据框,列结构为:年份、月份、各数据框对应的气候变量(示例如下)。

现有数据示例(共4份)

年份1月2月
199133.330.1
199232.129.7

目标数据格式示例

年份月份最高温(Tmax)最低温(Tmin)
19911月33.322.1
19912月30.120.1

目前用嵌套for循环实现,但处理大数据集效率低,求更高效的重塑方法。

现有for循环代码

rainvec <- c()
 for (i in 42:nrow(rain)) {
   for (j in 2:13) {
     rainvec <- c(rainvec, rain[[i,j]])
   }
  }

tminvec <- c()
 for (i in 1:nrow(tmin)) {
   for (j in 2:13) {
     tminvec <- c(tminvec, tmin[[i,j]])
   }
  }              
                    
tmaxvec <- c()
 for (i in 1:nrow(tmax)) {
   for (j in 2:13) {
     tmaxvec <- c(tmaxvec, tmax[[i,j]])
   }
  }                     
      
tmeanvec <- c()
 for (i in 1:nrow(tmean)) {
   for (j in 2:13) {
     tmeanvec <- c(tmeanvec, tmean[[i,j]])
   }
  }  
     
years <- sort(rep(tmean[[1]], 12))

months <- rep(1:12, nrow(tmin))
clim <- data.frame(years, months, rainvec, tminvec, tmaxvec, tmeanvec)
高效解决方案:使用tidyverse工具包

循环拼接向量的方式效率极低(每次c()都会重新分配内存),推荐用tidyr的pivot_longer()函数完成宽转长,再通过dplyr的inner_join()合并数据,全程向量化操作,处理大数据集速度会快很多。

步骤说明

  1. 给每个数据框的气候变量指定明确名称;
  2. 对每个数据框执行宽转长,将月份列转为行记录;
  3. 按年份和月份合并所有长格式数据框。

完整代码示例

# 加载工具包
library(tidyverse)

# 假设4个数据框分别为rain, tmin, tmax, tmean
# 逐个处理宽转长
rain_long <- rain %>%
  pivot_longer(cols = -年份, names_to = "月份", values_to = "降水量(Rain)")

tmin_long <- tmin %>%
  pivot_longer(cols = -年份, names_to = "月份", values_to = "最低温(Tmin)")

tmax_long <- tmax %>%
  pivot_longer(cols = -年份, names_to = "月份", values_to = "最高温(Tmax)")

tmean_long <- tmean %>%
  pivot_longer(cols = -年份, names_to = "月份", values_to = "平均温(Tmean)")

# 合并所有数据框
clim_final <- rain_long %>%
  inner_join(tmin_long, by = c("年份", "月份")) %>%
  inner_join(tmax_long, by = c("年份", "月份")) %>%
  inner_join(tmean_long, by = c("年份", "月份"))

# 查看结果
head(clim_final)

批量处理优化

如果需要简化代码,可将数据框放入列表,用批量函数处理:

# 批量处理示例
data_list <- list(
  降水量(Rain) = rain,
  最低温(Tmin) = tmin,
  最高温(Tmax) = tmax,
  平均温(Tmean) = tmean
)

clim_final <- data_list %>%
  imap(function(df, var_name) {
    df %>% pivot_longer(cols = -年份, names_to = "月份", values_to = var_name)
  }) %>%
  reduce(inner_join, by = c("年份", "月份"))

补充说明

  • 若月份列是纯数字(如1而非1月),可通过mutate(月份 = str_c(月份, "月"))转换格式;
  • 若各数据框年份范围不一致,可改用full_join()替代inner_join()保留所有年份记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:32:51