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

如何用循环或apply函数计算指定日期区间内变量的平均值?

自动化计算多日期区间的分组均值(针对dplyr新手)

首先,我先理清楚你的需求:你已经能手动计算单个日期区间的均值,但希望不用每次改日期,自动处理多个区间,而且作为新手不想写复杂的循环。下面给你两种简单易上手的方案,都是基于你已经熟悉的dplyr工具。


先回顾你的手动代码(方便对比)

你之前的手动实现是这样的:

library(dplyr)
retailavg <- google.mobility %>% 
  mutate(weekrange = date >= "2020-02-15" & date <= "2020-02-21") %>% 
  filter(weekrange) %>% 
  group_by(sub_region_2) %>% 
  summarise(avgretail = mean(retail_and_recreation_percent_change_from_baseline))

方案1:用purrr实现函数式自动化(新手友好)

purrr是tidyverse家族的工具,比基础循环更直观,代码可读性强,适合新手入门函数式编程。

步骤1:定义所有需要计算的日期区间

先把你要处理的所有日期区间整理成一个列表,每个元素存一个区间的起始和结束日期:

# 先加载需要的包
library(dplyr)
library(purrr)

# 定义日期区间列表,你可以根据需求添加更多区间
date_ranges <- list(
  c(start = "2020-02-15", end = "2020-02-21"),
  c(start = "2020-02-22", end = "2020-02-28"),
  c(start = "2020-07-21", end = "2020-07-28") # 你举的示例区间
)

步骤2:写一个计算单个区间均值的函数

把你手动写的逻辑封装成函数,输入一个日期区间,输出该区间的分组均值:

calculate_interval_avg <- function(date_range) {
  # 把字符日期转成日期格式
  start_date <- as.Date(date_range["start"])
  end_date <- as.Date(date_range["end"])
  
  google.mobility %>%
    # 过滤当前区间的日期
    filter(date >= start_date & date <= end_date) %>%
    group_by(sub_region_2) %>%
    summarise(
      # 计算零售娱乐的均值,加na.rm=TRUE避免缺失值导致结果为NA
      avg_retail = mean(retail_and_recreation_percent_change_from_baseline, na.rm = TRUE),
      # 可以顺便计算其他变量的均值,比如杂货店药店
      avg_grocery = mean(grocery_and_pharmacy_percent_change_from_baseline, na.rm = TRUE),
      # 保留区间的起止日期,方便后续区分不同区间的结果
      interval_start = start_date,
      interval_end = end_date
    )
}

步骤3:批量应用函数到所有区间

用map_dfr函数把上面的函数应用到所有日期区间,结果会自动合并成一个整洁的tibble:

# 自动计算所有区间的均值
all_avg_results <- map_dfr(date_ranges, calculate_interval_avg)

# 查看结果
head(all_avg_results)

方案2:基础for循环(适合理解循环逻辑)

如果你想学习基础的循环写法,也可以用for循环实现,逻辑和上面一致:

# 初始化一个空列表,用来存储每个区间的结果
all_results <- list()

# 遍历每个日期区间
for (i in seq_along(date_ranges)) {
  # 取出当前的日期区间
  current_range <- date_ranges[[i]]
  start_date <- as.Date(current_range["start"])
  end_date <- as.Date(current_range["end"])
  
  # 计算当前区间的均值
  current_result <- google.mobility %>%
    filter(date >= start_date & date <= end_date) %>%
    group_by(sub_region_2) %>%
    summarise(
      avg_retail = mean(retail_and_recreation_percent_change_from_baseline, na.rm = TRUE),
      interval_start = start_date,
      interval_end = end_date
    )
  
  # 把当前结果加入列表
  all_results[[i]] <- current_result
}

# 把列表里的所有结果合并成一个数据框
all_avg_results <- bind_rows(all_results)

新手额外小贴士

  1. 自动生成连续周区间:如果你的区间是连续的周(比如每周一个区间),不用手动写每个区间,可以用seq.Date自动生成:
    # 生成从2020-02-15开始的4个周起始日期
    start_dates <- seq(as.Date("2020-02-15"), by = "week", length.out = 4)
    # 每个周的结束日期是起始日期+6天(因为包含起始当天)
    end_dates <- start_dates + 6
    # 自动生成日期区间列表
    date_ranges <- pmap(list(start_dates, end_dates), ~c(start = .x, end = .y))
    
  2. 处理缺失值:一定要加na.rm = TRUE,否则数据里的缺失值会让均值计算结果变成NA,影响后续分析。
  3. 扩展多个变量:如果需要计算其他变量(比如公园、工作场所)的均值,直接在summarise里添加对应的mean()语句即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:22:56