Created
June 7, 2023 15:13
-
-
Save jonlachmann/5782aaa107a84eed6c84bb61ec6373d4 to your computer and use it in GitHub Desktop.
Calculate the number of days, weekdays or weeks in a month, quarter, half-year or year.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(lubridate) | |
# Function to count days, weekdays and weeks in a given month | |
counts <- function (year, month) { | |
# Get the number of days in the month | |
num_days <- days_in_month(as.Date(paste(year, month, "01", sep = "-"))) | |
# Initialize a counter | |
weekday_count <- 0 | |
week_count <- 0 | |
# Loop through each day of the month | |
for (day in 1:num_days) { | |
# Get the date | |
date <- as.Date(paste(year, month, day, sep = "-")) | |
# Check if the day is a weekday (Monday to Friday) | |
if (weekdays(date) %in% c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")) { | |
weekday_count <- weekday_count + 1 | |
} | |
if (weekdays(date) == "Wednesday") { | |
week_count <- week_count + 1 | |
} | |
} | |
# Return the weekday count | |
return(c(num_days, weekday_count, week_count)) | |
} | |
# Function to count days, weekdays and weeks per month within a given date range | |
counts_range <- function (start_date, end_date) { | |
# Convert start and end dates to date objects | |
start_date <- as.Date(start_date) | |
end_date <- as.Date(end_date) | |
# Get the start and end year and month | |
start_year <- as.numeric(format(start_date, "%Y")) | |
end_year <- as.numeric(format(end_date, "%Y")) | |
start_month <- as.numeric(format(start_date, "%m")) | |
end_month <- as.numeric(format(end_date, "%m")) | |
# Initialize a list to store the counts per month | |
counts_per_month <- list() | |
# Loop through each year and month | |
for (year in start_year:end_year) { | |
for (month in 1:12) { | |
# Check if the month is within the range | |
if ((year == start_year && month < start_month) || | |
(year == end_year && month > end_month)) { | |
next # Skip the iteration if the month is outside the range | |
} | |
# Count weekdays for the month | |
weekday_count <- counts(year, month) | |
# Store the count in the list | |
counts_per_month[[paste(year, month, sep = "-")]] <- weekday_count | |
} | |
} | |
# Return the counts per month | |
return(counts_per_month) | |
} | |
# Function to convert counts per month to counts per month, quarter, halfyear and year | |
per_q_h_y <- function (x) { | |
per_quarter <- rowSums(matrix(x, length(x) / 3, byrow = T)) | |
per_halfyear <- rowSums(matrix(x, length(x) / 6, byrow = T)) | |
per_year <- rowSums(matrix(x, length(x) / 12, byrow = T)) | |
return(list(m = x, q = per_quarter, h = per_halfyear, y = per_year)) | |
} | |
# Example usage | |
start_date <- "1900-01-01" | |
end_date <- "2100-12-31" | |
counts_per_month <- counts_range(start_date, end_date) | |
days_per_month <- unlist(lapply(counts_per_month, function (x) x[1])) | |
weekdays_per_month <- unlist(lapply(counts_per_month, function (x) x[2])) | |
weeks_per_month <- unlist(lapply(counts_per_month, function (x) x[3])) | |
days_per <- per_q_h_y(days_per_month) | |
weekdays_per <- per_q_h_y(weekdays_per_month) | |
weeks_per <- per_q_h_y(weeks_per_month) | |
days_mat <- matrix(unlist(lapply(days_per, summary)), 4, byrow = TRUE) | |
weekdays_mat <- matrix(unlist(lapply(weekdays_per, summary)), 4, byrow = TRUE) | |
weeks_mat <- matrix(unlist(lapply(weeks_per, summary)), 4, byrow = TRUE) | |
full_mat <- rbind(days_mat, weekdays_mat, weeks_mat)[, c(1, 4, 6)] | |
colnames(full_mat) <- c("Min.", "Mean", "Max.") | |
periodicities <- c("month", "quarter", "half-year", "year") | |
rownames(full_mat) <- c(paste0("Days per ", periodicities), paste0("Weekdays per ", periodicities), paste0("Weeks per ", periodicities)) | |
print(full_mat) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment