0

I need to convert an integer variable into a Date to run a chart measuring pre-baseline up to post intervention measurements. The variable is listed here:

project_month : int [1:29] -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 ...

I have tried several methods but none seem to work. Below are various ways I've attempted:

qic_u_chart <- QIH_data$data %>%
  mutate(x= as.Date(project_month))

Warning message: “Unknown or uninitialised column: data.”
Error in UseMethod("mutate_"): no applicable method for 'mutate_' applied to an object of class "NULL"

QIH_data <- QIH_data %>%
    mutate(project_month = 
    if_else(project_month <= as.Date("-1"), "baseline", "intervention"))

str(QIH_data)

Error in charToDate(x): character string is not in a standard unambiguous format

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • as.Date expects dates in formats such as "2021-05-29", i.e. an actual date. I suppose your month numbers correspond to actual dates... if so, then the first step would be to convert project_months into the date they correspond to. Is this what you're looking for? – giocomai May 29 '21 at 18:21
  • What is `QIH_data`? Right now you are using it like a list with a dataframe/tibble named `data` in it, but we have no idea if this is intended. – petrucci4prez May 29 '21 at 18:22
  • Please show your input in reproducible form using `dput` and also show the expected output. See the information at the top of the [tag:r] tag page regarding asking questions. – G. Grothendieck May 29 '21 at 20:31
  • A date must contain a year, a month and a day. Therefore, if you want to convert months into dates, you neeed to define a base year and a default day, the first for instance, and start from there. There is no such thing as a generic month. Once you have that, you can construct the dates as strings and use `lubridate::ymd()`. – xaviescacs May 29 '21 at 22:14
  • @xaviescacs: would you like to post an answer that gives an example of your suggestion? (You might be waiting for the OP to clarify/respond to your comment, which would also be reasonable.) – Ben Bolker May 29 '21 at 22:33
  • 1
    It would be easier to help if you create a small reproducible example along with expected output. Read about [how to give a reproducible example](http://stackoverflow.com/questions/5963269). – Ronak Shah May 30 '21 at 03:59

1 Answers1

0

If you have a integer that represents a month, positive or negative and possibly with gaps, if you choose a starting date you can do the following:

init_date <- "2018-01-01"
v <- purrr::map_dbl(project_month, ~ {
  lubridate::ymd(init_date) + months(.x)
}) %>% lubridate::as_date()
> v
[1] "2017-10-01" "2017-11-01" "2018-01-01" "2018-02-01" "2018-04-01"

If the variable project_month is part of a data frame, you can use dplyr::mutate:

tibble(
  project_month = c(-3,-2,0,1,3)
) %>% 
mutate(
  date = lubridate::ymd(init_date) + months(project_month)
)

There is an issue though. A month is not a time interval since not all months have the same amount of days, hours, etc. Threfore, this simple solution only works if the initial date is set in a day that exists in all months, namely, from 1 to 28.

> lubridate::ymd("2018-01-29") + months(1)
[1] NA
> lubridate::ymd("2018-01-28") + months(1)
[1] "2018-02-28"

Note that this is very similar to:

Split 52 weeks of data into 12 months

xaviescacs
  • 309
  • 1
  • 5
  • Thank you @xaviescacs. My project is definitely in a data.frame, but i am getting this error: init_date <- "2018-12-31" v <- purrr::map_dbl(month_id, ~ { lubridate::ymd(init_date) + months(.x) }) %>% as_date() v Error in purrr::map_dbl(month_id, ~{: object 'month_id' not found – Chris H May 30 '21 at 19:45
  • This worked: init_date <- "2018-12-31" tibble( project_month = c(-3,-2,0,1,3) ) %>% mutate( date = lubridate::ymd(init_date) + months(project_month) ) but is there a way to set it to the proper year? I have another variable called "month_id" to which is listed months 1-29, I am wondering if its possible to convert this to my starting year of 2018-12-31 to the present day today? – Chris H May 30 '21 at 19:50
  • I assume that you mean that the output with the initial date "2018-12-31" return some NA values. The reason iis that not every month has the 31th day. This is why this approach requires to choose a date with the day between 1 and 28. Do you need the day to be the last of each month? – xaviescacs May 30 '21 at 22:09