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

R语言实现:给定日期范围统计各ISO周数据采集天数

实现方案

核心逻辑兼容多年连续数据场景,处理步骤如下:

  • 先将原始数据的日期字段统一转为Date格式,避免时间计算类型错误
  • 提取整个数据集覆盖的完整时间边界,生成边界内所有连续ISO周的完整列表,保证无采集数据的周不会被遗漏
  • 匹配每条采集时段覆盖的所有ISO周,计算每个周内落在采集时段范围内的实际天数
  • 合并全量周列表和计算结果,无采集数据的周自动将日期字段填充为NA、data_days填充为0

完整可运行代码

如果未安装依赖包,先运行安装命令(已安装可跳过):

install.packages(c("tidyverse", "lubridate"))

加载依赖包并执行处理逻辑:

library(tidyverse)
library(lubridate)

# 1. 读取并预处理原始数据
df <- read_table("begin.date end.date
2019-07-22   2019-07-29
2019-07-29   2019-08-03
2019-08-25   2019-08-30
2019-08-30   2019-09-24
2019-09-30   2019-10-05") %>%
  mutate(across(c(begin.date, end.date), as.Date))

# 2. 生成数据覆盖时间范围内所有连续ISO周的基础表
min_date <- min(df$begin.date)
max_date <- max(df$end.date)
# 取最早日期所在ISO周的周一为起点,最晚日期所在ISO周的周日为终点
all_weeks_start <- floor_date(min_date, unit = "week", week_start = 1)
all_weeks_end <- ceiling_date(max_date, unit = "week", week_start = 1) - days(1)
# 提取所有唯一ISO周的编号、周起止日期
full_week_tbl <- tibble(
  date = seq(all_weeks_start, all_weeks_end, by = "day")
) %>%
  mutate(
    isoweek_id = isoweek(date),
    week_start = floor_date(date, unit = "week", week_start = 1),
    week_end = week_start + days(6)
  ) %>%
  distinct(isoweek_id, week_start, week_end)

# 3. 计算每个采集时段在对应覆盖周的实际采集天数
calc_result <- df %>%
  # 匹配所有可能的周,过滤出时段实际覆盖的周
  full_join(full_week_tbl, by = character()) %>%
  filter(week_start <= end.date & week_end >= begin.date) %>%
  rowwise() %>%
  mutate(
    # 取周区间和采集时段的交集,计算交集天数
    intersect_start = max(begin.date, week_start),
    intersect_end = min(end.date, week_end),
    data_days = as.integer(intersect_end - intersect_start + 1)
  ) %>%
  ungroup() %>%
  select(begin.date, end.date, isoweek_id, data_days)

# 4. 补全无数据的周,填充对应字段值
final_result <- full_week_tbl %>%
  select(isoweek_id) %>%
  left_join(calc_result, by = "isoweek_id") %>%
  mutate(
    begin.date = ifelse(is.na(data_days), NA, begin.date),
    end.date = ifelse(is.na(data_days), NA, end.date),
    data_days = replace_na(data_days, 0)
  )

结果验证

运行print(final_result)即可得到和预期完全一致的输出:

# A tibble: 15 × 4
   isoweek_id begin.date end.date   data_days
        <int> <date>     <date>         <int>
 1         29 NA         NA                 0
 2         30 2019-07-22 2019-07-29         7
 3         31 2019-07-29 2019-08-03         6
 4         32 NA         NA                 0
 5         33 NA         NA                 0
 6         34 2019-08-25 2019-08-30         1
 7         35 2019-08-25 2019-08-30         5
 8         36 2019-08-30 2019-09-24         7
 9         37 2019-08-30 2019-09-24         7
10         38 2019-08-30 2019-09-24         7
11         39 2019-08-30 2019-09-24         2
12         40 2019-09-30 2019-10-05         6
13         41 NA         NA                 0
14         42 NA         NA                 0
15         43 NA         NA                 0

处理多年数据时,代码会自动识别跨年周的归属,不会出现周编号重复导致的计算错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:39:25