如何聚合季节数据?请求绘制1920-2019年冬春季流量数据
Hey Kelsey, let's tackle this with a much cleaner, maintainable approach using dplyr and lubridate—no more manually typing out every start/end date! Here's how to calculate winter-spring discharge means for 1920-2019 and visualize the results:
Step 1: Load Packages & Retrieve Data
First, let's get your daily flow data (we'll keep things tidy from the start):
library(dataRetrieval) library(dplyr) library(lubridate) library(ggplot2) library(ggpmisc) # Retrieve daily discharge data siteNo <- "02202500" pCode <- "00060" daily <- readNWISdv(siteNo, pCode, "1920-10-01", "2019-09-30") %>% renameNWISColumns() %>% select(Date, Flow) %>% # Keep only columns we need mutate(Flow_m3s = Flow * 0.0283168) # Convert to m³/s upfront
Step 2: Define Winter-Spring Seasons
Your goal is to group December of year N to May of year N+1 as a single winter-spring season. We'll create a season_year column to label each date with the "target year" of its season (e.g., Dec 1920 to May 1921 gets labeled as 1921):
daily_seasonal <- daily %>% mutate( month = month(Date), # Assign season year: Dec belongs to next year's season; Jan-May belong to current year season_year = ifelse(month == 12, year(Date) + 1, year(Date)) ) %>% # Filter only winter-spring months (Dec, Jan, Feb, Mar, Apr, May) filter(month %in% c(12, 1, 2, 3, 4, 5)) %>% # Keep seasons within your 1920-2019 range (covers Dec 1920 to May 2019) filter(season_year >= 1921 & season_year <= 2019)
Step 3: Calculate Seasonal Mean Discharge
Now use dplyr to group by season_year and compute the mean flow:
seasonal_means <- daily_seasonal %>% group_by(season_year) %>% summarize( mean_flow_m3s = mean(Flow_m3s, na.rm = TRUE) # Handle missing values safely ) %>% ungroup() %>% # Add a midpoint date for smooth plotting (e.g., March of the season year) mutate(season_midpoint = ymd(paste0(season_year, "-03-15")))
Step 4: Plot the Seasonal Means
Now we can create your desired plot with the seasonal means, including the linear trend and stats:
my.formula <- mean_flow_m3s ~ season_midpoint p1 <- ggplot(data = seasonal_means, aes(x = season_midpoint, y = mean_flow_m3s)) + geom_line(color = "steelblue", linewidth = 1) + geom_smooth(method = "lm", se = FALSE, color = "darkred") + stat_poly_eq( formula = my.formula, eq.with.lhs = "italic(hat(y))~`=`~", aes(label = paste(..eq.label.., ..rr.label.., sep = "~~~")), parse = TRUE, color = "darkred" ) + theme_classic() + labs( x = "", y = expression(Discharge~(m^{3}~s^{-1})) ) + scale_x_date( breaks = "5 years", labels = scales::date_format("%Y"), expand = c(0, 0) ) + scale_y_continuous(limits = c(0, 600)) + theme(axis.text.x = element_text(angle = 45, hjust = 1)) p1
Key Fixes & Improvements Over Your Initial Code
- No manual date lists: We use
lubridateto dynamically assign seasons, which is far less error-prone and works for any date range. - Tidy data workflow:
dplyrpipes keep the code readable and avoid messy data frame reassignments. - Proper grouping: We explicitly group by
season_yearto calculate means for each winter-spring period, instead of usingsapplywhich wasn't targeting the right groups. - Missing value handling: Added
na.rm=TRUEto the mean calculation to avoid errors if there are gaps in the discharge data.
内容的提问来源于stack exchange,提问作者Kelsey

