How to have a difference in week units between two days (even if they're close but belong to different weeks) - r

I make an example to be clear:
if we speak of 2006/2007, the last day of 2006 was Sunday and the first of 2007 was Monday.
According to Italy (but also other countries), they belong to different weeks.
How can I obtain this information in R?
If I do:
difftime(as.Date("2007-01-01"),as.Date("2006-12-31"),units="weeks")
I get: 0.1428571
...but I would like to know some way to get 1 (as they differ of 1 week)

Your problem is that Monday should be the first day of the week. R packages usually consider Sunday to be the first day of the week.
My solution uses the lubridate package and reduces the day of the week by one. With this Mondays become Sundays, the first day of the week for lubridate. I then use floor_date to get the first day of the week and difftime the result.
library(lubridate)
dates <-c(as.Date("2007-01-01"),as.Date("2006-12-31"))
weekdays(dates)
#[1] "Monday" "Sunday"
tempdates <-update(dates,wdays=wday(dates)-1)
weekdays(tempdates)
#[1] "Sunday" "Saturday"
floor1 <-floor_date(tempdates, "week")
difftime(floor1[1],floor1[2], units = "weeks")
#Time difference of 1 weeks
January 1st and 2nd end up on the same week with this solution
dates <-c(as.Date("2007-01-02"),as.Date("2007-01-01"))
tempdates <-update(dates,wdays=wday(dates)-1)
floor1 <-floor_date(tempdates, "week")
difftime(floor1[1],floor1[2], units = "weeks")
#Time difference of 0 weeks

You could start with strftime(as.Date("2007-01-01"),"%U"), which identifies the week number in the year (look up strftime) and add the special case for the last week of a year maybe.

The difference in "weeks" depends on whether you are using "week" as 7 days or as a sequence number. This gives you an R method for working with the second definition of "week":
diff( c(as.numeric(format( as.Date("2007-01-01"), "%W")),
as.numeric(format(as.Date("2006-12-31"), "%W")) ))
[1] 51

Related

How to subtract a number of weeks from a yearweek/weeknumber in R?

I have a couples of weeknumbers of interest. Lets take '202124' (this week) as an example. How can I subtract x weeks from this week number?
Lets say I want to know the week number of 2 weeks prior, ideally I would like to do 202124 - 2 which would give me 202122. This is fine for most of the year however 202101 - 2 will give 202099 which is obviously not a valid week number. This would happen on a large scale so a more elegant solution is required. How could I go about this?
convert the year week values to dates subtract in days and format the output.
x <- c('202124', '202101')
format(as.Date(paste0(x, 1), '%Y%W%u') - 14, '%Y%V')
#[1] "202122" "202052"
To convert year week value to date we also need day of the week, I have used it as 1st day of the week.

How do i find week number from an arbitrary start date in R?

How do I find the week number from an arbitrary start date in R. Let's say I want my start date to be august 1st.
Using lubridate, you can do:
interval(today(), dmy("21-08-2020"))/weeks(1)
[1] 30.42857
Or from the date of interest to another date:
interval(dmy("21-08-2020"), dmy("21-09-2020"))/weeks(1)
[1] 4.428571
You can use difftime for this:
difftime("2020-08-21", Sys.Date(), units = "weeks")
# Time difference of 30.45238 weeks

How to convert a date as year/week to the first day of the week via POSIXct?

I want to convert
myDate=as.character("2017/02")
which is in the format year/week to a date that is the first day of this week. So I tried:
print(as.POSIXct(myDate,format="%Y/%U"))
However, this gives me
[1] "2017-05-03 CEST"
which is certainly not the first day of the second week in 2017.
Question: How do I need to change as.POSIXct(myDate,format="%Y/%U") in order to make it work as described above?
A year and a week is not a proper date. A day would need to be associated with the week. For example:
myDate=as.character("2017/02")
as.POSIXct(paste(myDate, "0"),format="%Y/%U %w")
#[1] "2017-01-08 EST"
this assumes the first day of the week is Sunday. If you prefer a Monday then see the %u option.
Here a possible approach:
myDate=as.character("2017/02")
Creation of the calendar (yyyy/dd/mm) of indicated year (E.g. 2017)
year_date<-seq.Date(as.Date(paste0(substr(myDate,1,4),"/01/01")),as.Date(paste0(substr(myDate,1,4),"/12/31")),by=1)
Using library ISOweek, this code finds the first day of each week
library("ISOweek")
first_day<-cumsum(ISOweekday(year_date)==1)
Extraction of the first day of the indicated week
year_date[which(first_day==as.numeric(unlist(strsplit(myDate,split="/"))[2]))[1]]
[1] "2017-01-09"
NB: in this example weeks start on monday

R: create index for xts time object from calendar week , e.g. 201501 ... 201553

I know how to get the week from an index, but don't know the other way around: how to create an index if I have the calendar weeks (in this case, from an SAP system with 0CALWEEK as 201501, 201502 ... 201552, 201553.
Found this:
How to Parse Year + Week Number in R?
but the day is needed and it's not clear how to set it, especially at the end of the year (Year - week - day: YEAR-53-01 does not always exist, since the first day of week 53 might be Monday, then 01 (Sunday) is not in that week.
I could try to get in the source system the first day of the corresponding week (through SQL) but thought R might do it easier...
Do you have any suggestions?
(Which first day of the week would be not important , since I will create all objects the same way and then merge/cbind them, then continue the analysis. If zoo is easier, I'll go with it)
Thanks!
The problem is that all indices end in 2015-07-29:
data <- 1:4
weeks <- c('201501','201502','201552','201553')
weeks_2 <- as.Date(weeks,format='%Y%w')
xts(data, order.by = weeks_2)
[,1]
2015-07-29 1
2015-07-29 2
2015-07-29 3
2015-07-29 4
test <- xts(data, order.by = weeks_2)
index(test)
[1] "2015-07-29" "2015-07-29" "2015-07-29" "2015-07-29"
You can use as.Date() function, I think is the easiest way:
weeks <- c('201501','201502','201552','201553')
as.Date(paste0(weeks,'1'),format='%Y%W%w') # paste a dummy day
## [1] "2015-01-05" "2015-01-12" "2015-12-28" NA
Where:
%W: Week 00-53 with Monday as first day of the week
or
%U: Week 01-53 with Sunday as first day of the week
%w: Weekday 0-6 Sunday is 0
For this year, week number 53 doesn't exist. And If you want to start with 2015-01-01, just set the right week day:
weeks <- c('201500','201501','201502','201551','201552')
as.Date(paste0(weeks,'4'),format='%Y%W%w')
## [1] "2015-01-01" "2015-01-08" "2015-01-15" "2015-12-24" "2015-12-31"
You may try with substr() and lubridate
library(lubridate)
# a number from your list: 201502
# set the year
x <- ymd("2015-01-1")
# retrieve second week
week(x) <- 2
x
[1] "2015-01-08"
you can use the result for your Index or rownames().
zoo and xts are great for time series once you have set the names,
be sure to remove any column with dates from your data frame

Calculating the number of weeks for each year based on dates using R

I have a dataset with dates of 2 different years (2009 and 2010) and would like to have the corresponding week number for each date.
My dataset is similar to this:
anim <- c(012,023,045,098,067)
dob <- c("01-09-2009","12-09-2009","22-09-2009","10-10-2010","28-10-2010")
mydf <- data.frame(anim,dob)
mydf
anim dob
1 12 01-09-2009
2 23 12-09-2009
3 45 22-09-2009
4 98 10-10-2010
5 67 28-10-2010
I would like to have variable "week" in the third column with the corresponding week numbers for each date.
EDIT:
Note: Week one begins on January 1st, week two begins on January 8th for each year
Any help would be highly appreciated.
Baz
Your definition of "week of year"
EDIT: Note: Week one begins on January 1st, week two begins on January 8th for each year
differs from the standard ones supported by strftime:
%U
Week of the year as decimal number (00–53) using Sunday as the first day 1
of the week (and typically with the first Sunday of the year as day 1 of
week 1). The US convention.
%W
Week of the year as decimal number (00–53) using Monday as the first day
of week (and typically with the first Monday of the year as day 1 of week
1). The UK convention.
So you need to compute it based on the day-of-year number.
mydf$week <- (as.numeric(strftime(as.POSIXct(mydf$dob,
format="%d-%m-%Y"),
format="%j")) %/% 7) + 1
Post 2011 Answer
library(lubridate)
mydf$week <- week(mydf$week)
lubridate package is straight-forward for day-to-day tasks like this.
If you want to do how many weeks (or 7 day periods) have passed between your date of interest and the first day of the year, regardless of what day of the week it was on the first of the year, the following is a solution (using floor_date from lubridate).
mydf$weeks <- difftime(mydf$dob, floor_date(mydf$dob, "year"), units = c("weeks")))

Resources