[R] previous monday date

Marc Schwartz marc_schwartz at me.com
Fri Sep 2 18:25:08 CEST 2011


> On Fri, Sep 2, 2011 at 9:59 AM, Marc Schwartz <marc_schwartz at me.com> wrote:
> 
>> On Sep 2, 2011, at 10:35 AM, Ben qant wrote:
>> 
>>> Hello,
>>> 
>>> I'm attempting to return the date (in form '%Y-%m-%d') of the Monday
>>> previous to the current date. For example: since it is 2011-09-02 today,
>> I
>>> would expect 2011-08-29 to be the return value.
>>> 
>>> I found the following in:
>>> http://www.mail-archive.com/r-help@r-project.org/msg144184.html
>>> 
>>> Start quote from link:
>>> prevmonday <- function(x) 7 * floor(as.numeric(x-1+4) / 7) + as.Date(1-4)
>>> 
>>> For example,
>>> 
>>>> prevmonday(Sys.Date())
>>> [1] "2011-08-15"
>>>> prevmonday(prevmonday(Sys.Date()))
>>> [1] "2011-08-15"
>>> 
>>> End quote from link.
>>> 
>>> But when I do it I get:
>>>> prevmonday <- function(x) 7 * floor(as.numeric(x-1+4) / 7) +
>> as.Date(1-4)
>>>> prevmonday(Sys.Date())
>>> Error in as.Date.numeric(1 - 4) : 'origin' must be supplied
>>> 
>>> I've tried setting the 'origin' argument in as.Date() in different ways,
>> but
>>> it returns inaccurate results.
>>> 
>>> Thanks,
>>> 
>>> Ben
>> 
>> 
>> If memory serves, this is because Gabor used the version of as.Date() from
>> his 'zoo' package in that post, which does not require an origin to be
>> specified, whereas the default as.Date() function in R's base package does:
>> 
>> prevmonday <- function(x) 7 * floor(as.numeric(x-1+4) / 7) + as.Date(1-4)
>> 
>>> prevmonday(Sys.Date())
>> Error in as.Date.numeric(1 - 4) : 'origin' must be supplied
>> 
>>> require(zoo)
>> Loading required package: zoo
>> 
>> Attaching package: 'zoo'
>> 
>> The following object(s) are masked from 'package:base':
>> 
>>   as.Date
>> 
>>> prevmonday(Sys.Date())
>> [1] "2011-08-29"
>> 
>> 
>> # Remove 'zoo' to use the base function
>> detach(package:zoo)
>> 
>>> prevmonday(Sys.Date())
>> Error in as.Date.numeric(1 - 4) : 'origin' must be supplied
>> 
>> 
>> # Fix the function to use base::as.Date()
>> prevmonday <- function(x) 7 * floor(as.numeric(x-1+4) / 7) + as.Date(1-4,
>> origin = "1970-01-01")
>> 
>>> prevmonday(Sys.Date())
>> [1] "2011-08-29"
>> 
>> 
>> See ?as.Date
>> 
>> HTH,
>> 
>> Marc Schwartz

On Sep 2, 2011, at 11:02 AM, Ben qant wrote:

> Oh OK, missed that.
> 
> Here is a solution using base: (already posted)
> 
> I didn't sort out the issue in  my email below but here is a (not very
> R'ish) solution:
> 
>> pm = function(x) {
> +   for(i in 1:7){
> +      if(format(as.Date(Sys.Date()-
> i),'%w') == 1){
> +      d = Sys.Date() - i;
> +     }
> +   }
> +   d
> + }
>> pm(Sys.Date())
> [1] "2011-08-29"


It occurs to me that another solution would be:

> as.Date(cut(Sys.Date(), "weeks"))
[1] "2011-08-29"


This uses cut.Date() to create a vector that contains the beginning of weekly intervals for each date value, with the week beginning on a Monday by default. Note that cut.Date() returns a factor, not a Date class object, hence the additional coercion of the result.

See ?cut.Date

So if you want that in a function wrapper, you could do:

prev.monday <- function(x) as.Date(cut(x, "weeks"))

> prev.monday(Sys.Date())
[1] "2011-08-29"


HTH,

Marc



More information about the R-help mailing list