Michael Szczepaniak
Michael Szczepaniak

Reputation: 2140

Why do these R commands behave differently in scripts vs. command line?

I've been working on a script in my Window 7 RStudio environment (R version 3.2.3) and I'm seeing what looks like a difference in behavior between what I see on the command line and how the same commands are run from within a script. Here is a simplified version of the script I was running:

if(!require(lubridate)) { install.packages("lubridate"); require(lubridate) }
startDate <- "2015-12-21"
endDate <- "2016-01-03"

rDateStrangeness <- function(startDate = "2015-12-21",
                             endDate = "2016-01-03") {
    sdate <- as.Date(startDate)
    edate <- as.Date(endDate)
    intervalDays <- seq(sdate, edate, by="days")
    for(day in intervalDays) {
        cat("day = ", day, ", as.character.Date(day) = ",
            as.character.Date(day) , ", wday(day) = ", wday(day), "\n")
    }
}

When I source and run rDateStrangeness(), I get this output:

day =  16790 , as.character.Date(day) =  16790 , wday(day) =  16790
day =  16791 , as.character.Date(day) =  16791 , wday(day) =  16791
day =  16792 , as.character.Date(day) =  16792 , wday(day) =  16792
day =  16793 , as.character.Date(day) =  16793 , wday(day) =  16793
day =  16794 , as.character.Date(day) =  16794 , wday(day) =  16794
day =  16795 , as.character.Date(day) =  16795 , wday(day) =  16795
day =  16796 , as.character.Date(day) =  16796 , wday(day) =  16796
day =  16797 , as.character.Date(day) =  16797 , wday(day) =  16797
day =  16798 , as.character.Date(day) =  16798 , wday(day) =  16798
day =  16799 , as.character.Date(day) =  16799 , wday(day) =  16799
day =  16800 , as.character.Date(day) =  16800 , wday(day) =  16800
day =  16801 , as.character.Date(day) =  16801 , wday(day) =  16801
day =  16802 , as.character.Date(day) =  16802 , wday(day) =  16802
day =  16803 , as.character.Date(day) =  16803 , wday(day) =  16803

But when I run the same commands from the command line

> sdate <- as.Date(startDate)
> edate <- as.Date(endDate)
> intervalDays <- seq(sdate, edate, by="days")
> day <- intervalDays[1]
> day.aschar <- as.character.Date(day)

I see this output

> day.aschar
[1] "2015-12-21"
> class(day.aschar)
[1] "character"
> wday(day.aschar)
[1] 2

I'm expecting the behavior I see on the command line, but it looks like the way the loop is accessing the date sequence is somehow different from what I'm expecting. I want to run wday within the loop, but it can't deal with how the loop is indexing into the date sequence.

Why am I seeing these differences between command line and script and how do I work around this?

Upvotes: 0

Views: 176

Answers (2)

Michael Szczepaniak
Michael Szczepaniak

Reputation: 2140

Digging deeper into this, it looks like R created a numeric iterator in the script which was not the behavior I expected or wanted. I found the answer to this in this related post:

Looping over a datetime object results in a numeric iterator

Specifically, I changed the loop slightly as shown below to get what I was after:

for(i in seq_along(intervalDays)) {
    day <- intervalDays[i]
    cat...
}

Upvotes: 2

andrnev
andrnev

Reputation: 410

How about if you change

intervalDays <- seq(sdate, edate, by="days")

to

intervalDays <- as.character(seq(sdate, edate, by="days"))

Here we esentially change the Date vector which the for loop cannot handle to a character vector which for loop can manage.

> for(day in intervalDays) {
+     cat("day = ", day, ", as.character.Date(day) = ",
+         as.character.Date(day) , ", wday(day) = ", wday(day), "\n")
+   }
day =  2015-12-21 , as.character.Date(day) =  2015-12-21 , wday(day) =  2 
day =  2015-12-22 , as.character.Date(day) =  2015-12-22 , wday(day) =  3 
day =  2015-12-23 , as.character.Date(day) =  2015-12-23 , wday(day) =  4 
day =  2015-12-24 , as.character.Date(day) =  2015-12-24 , wday(day) =  5 
day =  2015-12-25 , as.character.Date(day) =  2015-12-25 , wday(day) =  6 
day =  2015-12-26 , as.character.Date(day) =  2015-12-26 , wday(day) =  7 
day =  2015-12-27 , as.character.Date(day) =  2015-12-27 , wday(day) =  1 
day =  2015-12-28 , as.character.Date(day) =  2015-12-28 , wday(day) =  2 
day =  2015-12-29 , as.character.Date(day) =  2015-12-29 , wday(day) =  3 
day =  2015-12-30 , as.character.Date(day) =  2015-12-30 , wday(day) =  4 
day =  2015-12-31 , as.character.Date(day) =  2015-12-31 , wday(day) =  5 
day =  2016-01-01 , as.character.Date(day) =  2016-01-01 , wday(day) =  6 
day =  2016-01-02 , as.character.Date(day) =  2016-01-02 , wday(day) =  7 
day =  2016-01-03 , as.character.Date(day) =  2016-01-03 , wday(day) =  1 

Upvotes: 1

Related Questions