Reputation: 369
I would like to get the ISO week number from a given date in string format, where Monday is the first day of the week, and the week that contains the first Thursday of the year is considered to be the first week.
From other answers, I think strftime("2017-11-18", format = "%V")
suits my purpose the best.
However it doesn't work on Windows.
Any suggestions for alternatives with only the base package in R?
Upvotes: 2
Views: 10207
Reputation: 68
The Python datetime library has a native function for getting ISO year, week number and week day: https://docs.python.org/3/library/datetime.html#datetime.date.isocalendar. It returns a tuple with all three values, so just select the second element if you want to have the week number only.
Example:
from datetime import datetime
// Create a datetime object from your string
my_date = datetime.strptime('2017-11-18', '%Y-%m-%d')
// Get the tuple of ISO date values from your datetime object
my_iso_tuple = my_date.isocalendar()
// Get the ISO week number
my_iso_week_number = my_iso_tuple[1]
Upvotes: 1
Reputation: 34703
data.table
has an implementation of isoweek
which you might want to just port (it's easy to replicate with base
functionality)
# data.table approach:
isoweek <- function(x) {
x = as.IDate(x) # number of days since 1 Jan 1970 (a Thurs)
nearest_thurs = as.IDate(7L * (as.integer(x + 3L) %/% 7L))
year_start <- as.IDate(format(nearest_thurs, '%Y-01-01'))
1L + (nearest_thurs - year_start) %/% 7L
}
Ported to be strictly base
:
isoweek <- function(x) {
x = as.Date(x) # number of days since 1 Jan 1970 (a Thurs)
nearest_thurs = as.Date(7L * (as.integer(x + 3L) %/% 7L), origin = '1970-01-01')
year_start <- as.Date(format(nearest_thurs, '%Y-01-01'))
1L + (nearest_thurs - year_start) %/% 7L
}
Upvotes: 2
Reputation: 5003
Use the package lubridate
it has a function isoweek()
which gives you the ISOWeek of a given date
lubridate::isoweek("2017-11-18")
[1] 46
Now you just want to use the base packege. Here ist the code from lubridate for the ISO week
function (x)
{
xday <- make_datetime(year(x), month(x), day(x))
dn <- 1 + (wday(x) + 5)%%7
nth <- xday + ddays(4 - dn)
jan1 <- make_datetime(year(nth), 1, 1)
1L + as.integer(difftime(nth, jan1, units = "days"))%/%7L
}
we can take that an make it to something which only uses the base package.
myIsoweek <- function (x)
{
dateList <- as.list(strsplit(as.character(as.Date(x)),split = "-")[[1]])
names(dateList) <- c("year","month","day")
weekday <- as.POSIXlt(x)[["wday"]] + 1
xday <- ISOdate(dateList$year, dateList$month, dateList$day)
dn <- 1 + (weekday + 5)%%7
nth <- xday + 86400*(4 - dn)
jan1 <- ISOdate(format(nth,format = "%Y"), 1, 1)
1L + as.integer(difftime(nth, jan1, units = "days"))%/%7L
}
Upvotes: 4
Reputation: 2307
I believe strftime("2017-11-18", format = "%W")
should work in Windows.
Upvotes: 1