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

如何按列名模式批量计算tibble中的每日平均温度?

批量计算每日平均气温的高效解决方案

问题背景

现有如下tibble格式的温度数据,包含受访者ID及调查前后多日的最高温(tmax前缀)和最低温(tmin前缀)列:

> merged_data 
# A tibble: 168,747 × 15
   person_id      tmax_3 tmax_2 tmax_1 tmax0 tmax1 tmax2 tmax3 tmin_3 tmin_2 tmin_1 tmin0 tmin1 tmin2
   <chr>           <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl>
 1 0101500002010…   21.6   21.0   21.3  22.0  22.6  20.0  22.4   11.7   11.2   11.6  14.0  11.2  12.4
 2 0101500002010…   21.6   21.0   21.3  22.0  22.6  20.0  22.4   11.7   11.2   11.6  14.0  11.2  12.4
# ℹ 168,737 more rows
# ℹ 1 more variable: tmin3 <dbl>
# ℹ Use `print(n = ...)` to see more rows

需求是高效计算每日平均气温(当日最高温+最低温的平均值),替代重复的mutate操作,尤其适合存在调查前后各100天温度列的场景。此前使用的ChatGPT代码因列名匹配错误无法运行。

原代码问题分析

ChatGPT推荐的代码存在两个核心问题:

  1. 列名匹配错误:paste0("tmin_", cur_column())会将tmax_3拼接成tmin_tmax_3,并非对应的tmin_3列;
  2. rowwise()会大幅降低大数据集的处理效率,16万行的数据集运行速度极慢。

高效解决方案

方案一:使用across结合列名替换(推荐,高效向量操作)

利用across批量处理tmax列,通过字符串替换匹配对应的tmin列,无需逐行操作:

library(dplyr)
library(stringr)

merged_data <- merged_data %>%
  mutate(
    across(
      starts_with("tmax"), 
      ~ (.x + get(str_replace(cur_column(), "^tmax", "tmin"))) / 2,
      .names = "tavg{str_replace(.col, 'tmax', '')}"
    )
  )

说明:

  • str_replace(cur_column(), "^tmax", "tmin")将当前tmax列名替换为对应的tmin列名(如tmax_3→tmin_3,tmax3→tmin3);
  • .names参数直接生成目标列名(如tmax_3→tavg_3,tmax0→tavg0);
  • 全程为向量化操作,处理16万行数据效率远高于rowwise()。

方案二:使用pivot转换(直观,适合多列场景)

通过长表-宽表转换的方式,将同天数的tmax和tmin聚合计算后再转回宽表,代码更简洁直观:

library(dplyr)
library(tidyr)

merged_data <- merged_data %>%
  # 转换为长表,拆分出温度类型(tmax/tmin)和天数后缀
  pivot_longer(
    cols = starts_with(c("tmax", "tmin")),
    names_to = c(".value", "day"),
    names_pattern = "(tmax|tmin)(.*)"
  ) %>%
  # 计算每日平均气温
  mutate(tavg = (tmax + tmin) / 2) %>%
  # 转回宽表,恢复原列结构
  pivot_wider(
    names_from = day,
    values_from = c(tmax, tmin, tavg)
  ) %>%
  # 保持person_id在第一列
  select(person_id, everything())

说明:

  • names_pattern = "(tmax|tmin)(.*)"将列名拆分为温度类型和天数部分(如tmax_3拆分为tmax和_3);
  • 该方法无需手动处理列名匹配,适合列数极多(如前后100天)的场景,逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:24:51