Find Out the Number of Days of a Month in R

Find out the number of days of a month in R

You can write simple function to do that:

numberOfDays <- function(date) {
m <- format(date, format="%m")

while (format(date, format="%m") == m) {
date <- date + 1
}

return(as.integer(format(date - 1, format="%d")))
}

Invoke as:

> date = as.Date("2011-02-23", "%Y-%m-%d")
> numberOfDays(date)
[1] 28
> date # date is unchanged
[1] "2011-02-23"

Counting number of days in months in r

library(dplyr)

df %>%
# distinct(date) %>% # unnecessary if no dupe dates
mutate(month = lubridate::floor_date(date, "month")) %>%
count(month)

Result

       month n
1 2005-12-01 2
2 2006-01-01 3
3 2006-02-01 1
4 2007-03-01 3
5 2007-04-01 2

Data used:

df <- structure(list(date = structure(c(13145, 13148, 13149, 13150, 
13151, 13183, 13574, 13575, 13578, 13613, 13614), class = "Date")), row.names = c(NA,
-11L), class = "data.frame")

Count the number of days in each month of a date range

Consider the functions f1, f2, f3 below

f1 <- function(d_first,d_last){
d_first <- as.Date(d_first)
d_last <- as.Date(d_last)

D <- seq(d_first, d_last, 1) # generate all days in [d_first,d_last]
M <- unique(format(D, "%m")) # all months in [d_first,d_lst]

f2 <- function(x) length(which(format(D, "%m") == x)) # returns number of days in month x
res <- vapply(M,f2,numeric(1))
return(cbind(unique(format(D, "%Y-%m")),res))
}
f3 <- function(k) f1(df$start[k],df$end[k])

output <- sapply(1:nrow(df), f3)

which yields

> output 
[[1]]
res
01 "2014-01" "27"
02 "2014-02" "3"

[[2]]
res
02 "2014-02" "25"
03 "2014-03" "31"
04 "2014-04" "29"

[[3]]
res
02 "2014-02" "23"
03 "2014-03" "7"

From here on now, the rest is a matter of formatting. Indeed, a simple do.call(rbind, output) will do the trick

> do.call(rbind, output)
res
01 "2014-01" "27"
02 "2014-02" "3"
02 "2014-02" "25"
03 "2014-03" "31"
04 "2014-04" "29"
02 "2014-02" "23"
03 "2014-03" "7"

Of the top of my head, to have the IDs you could set f4 <- function(k) cbind(df$id[k], f3(k)) and thus

> do.call(rbind, sapply(1:nrow(df), f4))
res
01 "1" "2014-01" "27"
02 "1" "2014-02" "3"
02 "1" "2014-02" "25"
03 "1" "2014-03" "31"
04 "1" "2014-04" "29"
02 "2" "2014-02" "23"
03 "2" "2014-03" "7"

But there probably are cleverer solutions.

Get the number of days from the date column

You need to first get the column MONTH to Date and then use any of the function shown here to get number of days in a month.

as.Date(paste0(1, df$MONTH), "%d%b,%Y")
#[1] "2017-01-01" "2017-02-01" "2017-03-01" "2017-04-01" "2017-05-01" "2017-06-01"
# "2017-07-01" "2017-08-01" "2017-09-01" "2017-10-01" "2017-11-01" "2017-12-01"

Hmisc::monthDays(as.Date(paste0(1, df$MONTH), "%d%b,%Y"))
#[1] 31 28 31 30 31 30 31 31 30 31 30 31

data

df <- structure(list(MONTH = structure(c(5L, 4L, 8L, 1L, 9L, 7L, 6L, 
2L, 12L, 11L, 10L, 3L), .Label = c("Apr,2017", "Aug,2017", "Dec,2017",
"Feb,2017", "Jan,2017", "Jul,2017", "Jun,2017", "Mar,2017", "May,2017",
"Nov,2017", "Oct,2017", "Sep,2017"), class = "factor")), class =
"data.frame", row.names = c(NA, -12L))

R: number of days to month end using lubridate

In lubridate you can do:

days_in_month(now()) - mday(now())

Although that gives you a named vector, so it's better to do

as.numeric(days_in_month(now()) - mday(now()))
#> [1] 27

Thanks to @H1 for pointing out we can use now() instead of month(now())

How to count the number of days, weeks, months in a date column of a dataframe in r?

Use format() with the following codes:

date = strptime('2005-02-28', format='%Y-%m-%d')

format(date, '%j') # Decimal day of the year

format(date, '%U') # Decimal week of the year (starting on Sunday)

format(date, '%W') # Decimal week of the year (starting on Monday)

format(date, '%m') # Decimal month

Output:

[1] "059"
[1] "09"
[1] "09"
[1] "02"

Source

How to specify the number of days in each month for specific year using R?

You can get the last day of the month by moving back one day from the first of the next month. So, try this:

numDays <- function(month,year){
as.numeric(strftime(as.Date(paste(year+month%/%12,month%%12+1,"01",sep="-"))-1,"%d"))
}

Testing:

numDays(2,2012)
[1] 29
numDays(2,2011)
[1] 28
numDays(1,2011)
[1] 31
numDays(12,2011)
[1] 31
# vector of all month days in year 2000
sapply(1:12,numDays,2000)
[1] 31 29 31 30 31 30 31 31 30 31 30 31

Counts of numbers of date for service use in each month

Here's a {tidyverse} solution.

  1. Use dplyr::summarize() and seq() to generate the full range of dates for each observation.
    • I include end - 1 in seq() to not include the end date in the count, consistent with your example.
  2. Convert these to months using lubridate::floor_date(unit = "month") (technically, changes each date to the first of the month).
  3. dplyr::count() up month-days for each id.
  4. Because you want columns for months with no observations in your output, I wrote a function to add unobserved months based on tidyr::complete().
  5. Finally, tidyr::pivot_wider() to get a column for each month.
library(tidyverse)
library(lubridate)

complete_months <- function(.data, month, ..., fill = list()) {
month <- pull(.data, {{ month }})
firstday <- floor_date(min(month, na.rm = TRUE), unit = "year")
lastday <- ceiling_date(max(month, na.rm = TRUE), unit = "year") - 1
allmonths <- seq(firstday, lastday, by = "month")
complete(.data, month = allmonths, ..., fill = fill)
}

month_counts <- df %>%
mutate(across(start:end, ymd)) %>%
group_by(id, obs = row_number()) %>%
summarize(
# use end - 1 in seq() to omit end date from count
month = floor_date(seq(start, end - 1, by = 1), unit = "month"),
.groups = "drop"
) %>%
count(month, id) %>%
complete_months(month, id, fill = list(n = 0)) %>%
mutate(month = strftime(month, "%Y_%b")) %>%
pivot_wider(
names_from = month,
values_from = n
)

month_counts

# # A tibble: 2 x 25
# id `2018_Jan` `2018_Feb` `2018_Mar` `2018_Apr` `2018_May` `2018_Jun`
# <chr> <int> <int> <int> <int> <int> <int>
# 1 A 0 0 0 30 31 30
# 2 B 0 0 0 0 0 0
# # ... with 18 more variables: `2018_Jul` <int>, `2018_Aug` <int>,
# # `2018_Sep` <int>, `2018_Oct` <int>, `2018_Nov` <int>, `2018_Dec` <int>,
# # `2019_Jan` <int>, `2019_Feb` <int>, `2019_Mar` <int>, `2019_Apr` <int>,
# # `2019_May` <int>, `2019_Jun` <int>, `2019_Jul` <int>, `2019_Aug` <int>,
# # `2019_Sep` <int>, `2019_Oct` <int>, `2019_Nov` <int>, `2019_Dec` <int>


Related Topics



Leave a reply



Submit