如何按日期为DataFrame的Jevons列分配不同权重并生成加权列?
Hi Jay, let's work through this weighted Jevons calculation problem together! The key here is to conditionally apply weights based on the year extracted from your month column, which is exactly what dplyr::case_when() was made for. Below are two straightforward approaches to solve this:
Approach 1: Direct Conditional Calculation (No Intermediate Columns)
This method uses case_when() inside mutate() to apply the correct weight based on the year, without creating extra columns unless you want them.
First, let's load the dplyr package (it's essential for tidy data manipulation):
library(dplyr)
Process onlinedf:
onlinedf <- onlinedf %>% mutate( weightedJevons = Jevons * case_when( # Extract year from the first 4 characters of `month` substr(month, 1, 4) == "2014" ~ 23.2, substr(month, 1, 4) == "2015" ~ 25.6, # Handle unexpected years with NA (adjust if needed) TRUE ~ NA_real_ ) )
Process offlinedf:
Just swap out the weights to match the offline rules:
offlinedf <- offlinedf %>% mutate( weightedJevons = Jevons * case_when( substr(month, 1, 4) == "2014" ~ 76.8, substr(month, 1, 4) == "2015" ~ 74.5, TRUE ~ NA_real_ ) )
Approach 2: Use a Weight Lookup Table (Scalable for More Years)
If you ever need to add more years or update weights later, a lookup table is cleaner and easier to maintain.
First, define your weight rules in a separate table:
weight_lookup <- tibble( year = c("2014", "2015"), online_weight = c(23.2, 25.6), offline_weight = c(76.8, 74.5) )
Process onlinedf:
onlinedf <- onlinedf %>% # Extract year from `month` mutate(year = substr(month, 1, 4)) %>% # Join with the lookup table to get the correct weight left_join(weight_lookup, by = "year") %>% # Calculate weighted Jevons mutate(weightedJevons = Jevons * online_weight) %>% # Remove intermediate columns if desired select(-year, -online_weight, -offline_weight)
Process offlinedf:
offlinedf <- offlinedf %>% mutate(year = substr(month, 1, 4)) %>% left_join(weight_lookup, by = "year") %>% mutate(weightedJevons = Jevons * offline_weight) %>% select(-year, -online_weight, -offline_weight)
Bonus: Robust Year Extraction with lubridate
If your month column might have inconsistent formats (e.g., numbers instead of strings), use the lubridate package to safely parse dates and extract years:
library(lubridate) onlinedf <- onlinedf %>% mutate( year = as.character(year(ym(month))), # Convert to date, extract year as string weightedJevons = Jevons * case_when( year == "2014" ~ 23.2, year == "2015" ~ 25.6, TRUE ~ NA_real_ ) )
Both approaches will correctly apply the year-specific weights to your Jevons column, generating the weightedJevons you need. The first method is quick for simple cases, while the second is better for long-term maintainability.
内容的提问来源于stack exchange,提问作者Jay J

