将月份转换为连续整数:Kernel Regression数据预处理及逆向转换需求
Hey there! Let’s work through this problem together. You’ve got monthly observation counts spanning 2000 to 2018, need to convert those dates to sequential integers (where Jan 2000 = 1) for kernel regression, then map those integers back to dates for plotting. Here’s a straightforward R solution tailored to your needs:
First, let’s turn that space-separated raw data into a proper data frame with year, month, and observation count columns:
# Your raw input data raw_data <- c(2005, 07, 2, 2005, 10, 4, 2005, 12, 2, 2006, 01, 4, 2006, 02, 1, 2006, 07, 2, 2006, 08, 1, 2006, 10, 3) # Reshape into a 3-column data frame obs_df <- data.frame( year = raw_data[seq(1, length(raw_data), 3)], month = raw_data[seq(2, length(raw_data), 3)], count = raw_data[seq(3, length(raw_data), 3)] )
Next, we’ll create a formal date column (using the first day of each month as a consistent anchor):
# Combine year, month, and day (first of the month) into a date obs_df$date <- as.Date(paste(obs_df$year, obs_df$month, "01", sep = "-"))
We’ll calculate the integer offset from your start date (Jan 2000) so that each month gets a unique sequential number:
# Define your starting date (Jan 2000 = integer 1) start_date <- as.Date("2000-01-01") # Install lubridate if you haven't already # install.packages("lubridate") # Calculate sequential integer: (year difference * 12) + month difference + 1 obs_df$seq_int <- as.integer( (lubridate::year(obs_df$date) - lubridate::year(start_date)) * 12 + (lubridate::month(obs_df$date) - lubridate::month(start_date)) + 1 ) # Check the result (Jan 2006 = 73, which makes sense: 6 years *12 =72 +1 =73) head(obs_df)
Once you’ve run your kernel regression, you’ll need to convert those sequential integers back to dates for visualization. Here’s a reusable function to do that:
# Function to convert sequential integer to date int_to_date <- function(seq_int, start_date = as.Date("2000-01-01")) { months_since_start <- seq_int - 1 years <- months_since_start %/% 12 months <- months_since_start %% 12 + 1 as.Date(paste(lubridate::year(start_date) + years, months, "01", sep = "-")) } # Test it: integer 13 should return Jan 2001 int_to_date(13) # Output: "2001-01-01" # Example: Convert a full sequence of integers (2000-2018 = 216 months) pred_seq <- seq(1, 216, 1) pred_dates <- int_to_date(pred_seq)
If you’re using ggplot2 for plotting, here’s how to integrate the converted dates:
# Install ggplot2 if you haven't already # install.packages("ggplot2") library(ggplot2) # Example: Simulate kernel regression predictions (replace with your actual results) pred_df <- data.frame( seq_int = pred_seq, pred_count = rnorm(216, mean = 2, sd = 0.5) ) pred_df$date <- int_to_date(pred_df$seq_int) # Plot observed data + regression line ggplot() + geom_point(data = obs_df, aes(x = date, y = count), color = "darkblue", alpha = 0.7) + geom_line(data = pred_df, aes(x = date, y = pred_count), color = "firebrick", linewidth = 1) + labs(x = "Date", y = "Observation Count", title = "Kernel Regression of Monthly Observations") + theme_minimal()
内容的提问来源于stack exchange,提问作者Sergio Olalla

