tidyverse / lubridate

Make working with dates in R just that little bit easier
https://lubridate.tidyverse.org
GNU General Public License v3.0
733 stars 207 forks source link

as.Date() changes behavior when called with gurobipy's Model() and lubridate #970

Closed alabeli closed 3 years ago

alabeli commented 3 years ago

Apologies for not being able to reproduce my example using reprex since my issue involves using gurobipy in R which needs a proprietary license.

I am using reticulate (v1.18) to use python's gurobipy package that supports gurobi 9.1.1. Once I call Model() class from gurobipy and then if I run lubridate functions like ymd() or mdy_hms() or guess_formats(), the behavior of as.Date("year-weeknumber-dayofweek", format = "%Y-%U-%A") changes. Please note, only few functions from lubridate conflicts with Model(). In my knowledge, I have had issues with the 3 mentioned here.

Example in words:

For the year 2016, week number 00, and day of week Tuesday I get "2016-01-05" as output normally. Once I call Model() and run ymd(), I get NA for the same combination.

Example in code:

Just as a note, python returns "2015-12-29" consistently before or after running Model() which is different from "2016-01-05". I was also expecting the date "2015-12-29" as output from as.Date() but I think that's a separate issue.

It will be very helpful if you could explain what could be going on here. For now, I am using ISOweek package which gives consistent performance even after calling Model() and using some lubridate functions. I have also contacted gurobi in parallel but some insight into this will help me much.

lubridate version is 1.7.9 tidyverse version is 1.3.0 base version is 3.6.3

Happy to provide more information as required.


```{r}
reticulate::use_python("<my-python-path>", required = TRUE)
library(lubridate)
library(tidyverse)
library(reticulate)

Problem

Gurobipy's Model class alters behavior of date formatting in R when used with lubridate functions ymd and/or mdy_hms.

Reproducible example

Before calling Model()

We want to correct a date 2016-01-01 to align with Tuesday as the day of the week. Below code achieves that using %Y (year), %U (week number), and %A (day of week). The value of start_date_sample after running the below chunk is 2016-01-05

Below is my code.


```{r}
sample_string <- "1/1/2016 12:00:00 AM"
sample_date <- ymd(mdy_hms(sample_string))
sample_dow <- "Tuesday"               
year_week_day <- str_glue("{getyear}-{getweek}-{getday}",
       getyear = year(sample_date),
       getweek = format(sample_date, "%U"),
       getday = sample_dow
     )
start_date_sample <- as.Date(year_week_day, format = "%Y-%U-%A")
year_week_day
start_date_sample

Output of start_date_sample = "2016-01-05"

Python version

Same format argument gives a different result in python.

import datetime

d = "2016-00-Tuesday"
datetime.datetime.strptime(d, "%Y-%U-%A")

Call Model() of gurobipy

from gurobipy import *

m = Model()

After calling Model()

Below chunk gives output of start_date_sample as NA. If you refresh the session, comment sample_date assignment line and uncomment the line that is already commented, you will get the desired output of 2016-01-05.

sample_string <- "1/1/2016 12:00:00 AM"
sample_date <- ymd(mdy_hms(sample_string))
#sample_date <- as.Date(sample_string, format = "%m/%d/%Y %H:%M:%S")
sample_dow <- "Tuesday"               
year_week_day <- str_glue("{getyear}-{getweek}-{getday}",
       getyear = year(sample_date),
       getweek = format(sample_date, "%U"),
       getday = sample_dow
     )
start_date_sample <- as.Date(year_week_day, format = "%Y-%U-%A")
year_week_day
start_date_sample

Output of start_date_sample = NA

Python version

Python output is unchanged after calling Model().

import datetime

d = "2016-00-Tuesday"
datetime.datetime.strptime(d, "%Y-%U-%A")
vspinu commented 3 years ago

The last usage of lubridate function is this one sample_date <- ymd(mdy_hms(sample_string)) . You need to report if anything is wrong with that statement.

One wrong thing is that ymd is a parsing function. You need as_date there. as_date(mdy_hms(sample_string)).

If you can cut all the code down and report the result mdy_hms(sample_string)) before and after calling Model, then we might be able to help.

alabeli commented 3 years ago

Hello,

Thank you for your response. I will use as_date instead of ymd as per your suggestion, thank you for pointing that out.

Sorry I wanted to provide complete context so provided the entire code. I was able to understand from Gurobi that when I call Model class, it silently changes locale of my R process. So I should reset locale vars after I call Model(). LC_TIME was getting reset to "C" instead of "en_US.UTF-8".

For anyone who may face this issue, running Sys.setlocale(category="LC_ALL", locale="en_US.UTF-8") after calling Model() solved the issue.

Thank you for your time. Closing this issue.