基于R语言的供需动态计算及净赤字列生成技术问询
Alright, let's work through this problem. You've got 50 days of supply/demand data with a supply-demand difference column, and you need to add a net deficit column while tracking a reservoir with a 200-unit capacity. Here's how to implement this logic cleanly in R, with both base R and tidyverse options:
First, let's set up sample data to test with
I'll create a dummy dataset that mimics your setup—feel free to swap this out with your actual data:
set.seed(123) # For reproducibility df <- data.frame( Day = 1:50, Demand = sample(50:150, 50, replace = TRUE), Supply = sample(60:160, 50, replace = TRUE) ) df$Supply_Demand_Diff <- df$Supply - df$Demand # Your existing difference column
Base R Approach (Using a Loop)
Since we need to track the reservoir level day-over-day (a cumulative state), a loop works well here for straightforward readability:
# Initialize reservoir and net deficit column reservoir <- 0 df$net_deficit <- 0 for (i in seq(nrow(df))) { daily_gap <- df$Supply[i] - df$Demand[i] if (daily_gap < 0) { # Demand exceeds supply: use reservoir to cover the gap required <- abs(daily_gap) if (reservoir >= required) { # Reservoir has enough to cover the entire deficit reservoir <- reservoir - required df$net_deficit[i] <- 0 } else { # Reservoir can't cover all demand—net deficit is the unmet amount df$net_deficit[i] <- required - reservoir reservoir <- 0 } } else { # Supply meets or exceeds demand: store excess in reservoir (if there's space) excess <- daily_gap reservoir <- min(reservoir + excess, 200) # Cap at 200 (full capacity) df$net_deficit[i] <- 0 } }
Tidyverse Approach (Functional Style with accumulate)
If you prefer a pipe-based workflow, use purrr::accumulate to carry over the reservoir state between days:
library(dplyr) library(purrr) df <- df %>% mutate( # Track both reservoir level and net deficit with accumulate daily_state = accumulate(1:nrow(.), function(prev_state, day_idx) { daily_gap <- Supply[day_idx] - Demand[day_idx] current_reservoir <- prev_state$reservoir if (daily_gap < 0) { required <- abs(daily_gap) if (current_reservoir >= required) { new_reservoir <- current_reservoir - required net_def <- 0 } else { net_def <- required - current_reservoir new_reservoir <- 0 } } else { excess <- daily_gap new_reservoir <- min(current_reservoir + excess, 200) net_def <- 0 } list(reservoir = new_reservoir, net_deficit = net_def) }, .init = list(reservoir = 0, net_deficit = 0)) %>% tail(-1) # Drop the initial empty state ) %>% # Extract values from the state list into columns mutate( net_deficit = map_dbl(daily_state, ~.$net_deficit), reservoir_level = map_dbl(daily_state, ~.$reservoir), daily_state = NULL # Clean up the list column if not needed )
Notes on the Logic
- I added handling for the edge case where the reservoir can't cover the full demand (you didn't mention this, but it's a realistic scenario). If your business rule says net deficit should always be 0 even if demand isn't met, just set
df$net_deficit[i] <- 0in that branch. - Both methods ensure the reservoir never exceeds its 200-unit capacity—excess supply beyond that is discarded.
- The
reservoir_levelcolumn is optional, but it's helpful to verify the reservoir is behaving as expected.
内容的提问来源于stack exchange,提问作者89_Simple
相关产品推荐
相关产品推荐

