如何筛选DataFrame中处于起止日期区间的日期列并计算均值
问题描述
我有一个包含start_date和end_date列的数据集,这两列的日期跨度为7至40天;另有约50列,列名为2021-01-01至2021-12-22、间隔16天的日期。需编写代码找出每行起止日期之间的日期列,计算这些列的均值并生成新列,最后删除所有日期列。
以下是用于创建数据集的代码:
rm(list = ls()) library(lubridate) # Create date columns with 16-day intervals (ensure correct order here!) date_cols <- as.character(seq(ymd("2021-01-01"), ymd("2022-12-30"), by = "16 days")) # Use as.character # Determine the desired number of rows num_rows <- 100 # Adjust this if needed # Create an empty data frame with all columns (no changes here) df <- data.frame(matrix(ncol = length(date_cols) + 2, nrow = num_rows)) colnames(df) <- c("start_date", "end_date", date_cols) # Assign column names for all columns # Fill the start_date and end_date columns (no changes here) start_date <- sample(seq(ymd("2021-01-01"), ymd("2022-12-30"), by = "day"), num_rows) end_date <- start_date + sample(7:40, num_rows, replace = TRUE) df$start_date <- start_date df$end_date <- end_date # Fill the date columns with random numbers (no changes here) df[, date_cols] <- runif(num_rows * length(date_cols), min = 1, max = 2) # Print the dataset head(df)
注:日期列代表针对不同点(行)提取的栅格数据,需匹配对应日期的数据。
解决方案
可以用dplyr结合purrr处理每行的日期筛选和均值计算,步骤如下:
1. 加载必要工具包
确保安装并加载dplyr和purrr,配合已有的lubridate使用:
library(dplyr) library(purrr)
2. 转换日期列名为日期对象
先把列名里的日期字符串转成Date类型,方便后续区间比较:
date_col_dates <- ymd(date_cols)
3. 逐行计算目标均值
用pmap_dbl遍历每行的起止日期,筛选出落在区间内的日期列,计算均值并生成新列date_range_mean:
df <- df %>% mutate(date_range_mean = pmap_dbl(., function(start_date, end_date, ...) { # 提取当前行所有日期列的数值 row_vals <- c(...) # 筛选出在[start_date, end_date]区间内的日期列索引 valid_indices <- which(date_col_dates >= start_date & date_col_dates <= end_date) # 计算均值,无符合条件列时返回NA(可按需调整) if(length(valid_indices) == 0) { NA_real_ } else { mean(row_vals[valid_indices]) } }))
4. 删除所有原日期列
保留start_date、end_date和新生成的均值列,移除原日期列:
df <- df %>% select(start_date, end_date, date_range_mean)
完整整合代码
将所有步骤整合后,运行即可得到最终结果:
rm(list = ls()) library(lubridate) library(dplyr) library(purrr) # 创建数据集(原代码保留) date_cols <- as.character(seq(ymd("2021-01-01"), ymd("2022-12-30"), by = "16 days")) num_rows <- 100 df <- data.frame(matrix(ncol = length(date_cols) + 2, nrow = num_rows)) colnames(df) <- c("start_date", "end_date", date_cols) start_date <- sample(seq(ymd("2021-01-01"), ymd("2022-12-30"), by = "day"), num_rows) end_date <- start_date + sample(7:40, num_rows, replace = TRUE) df$start_date <- start_date df$end_date <- end_date df[, date_cols] <- runif(num_rows * length(date_cols), min = 1, max = 2) # 处理数据 date_col_dates <- ymd(date_cols) df <- df %>% mutate(date_range_mean = pmap_dbl(., function(start_date, end_date, ...) { row_vals <- c(...) valid_indices <- which(date_col_dates >= start_date & date_col_dates <= end_date) if(length(valid_indices) == 0) { NA_real_ } else { mean(row_vals[valid_indices]) } })) %>% select(start_date, end_date, date_range_mean) # 查看结果 head(df)
内容的提问来源于stack exchange,提问作者jwell123
相关产品推荐
相关产品推荐

