How can I create a new variable for seasons from a date-variable?

Viewed 133

I have a dataframe of comments where one column df$date corresponds to the dates when the comment was made, expressed as shown below:

[1] "2019-06-01" "2019-07-01" "2019-10-01" "2019-10-01" "2019-09-01" "2019-04-01" "2019-04-01" "2019-04-01" "2019-04-01"
 [10] "2019-04-01" "2018-08-01" "2018-08-01" "2018-08-01" "2018-07-01" "2018-08-01" "2018-07-01" "2018-07-01" "2018-06-01"

I want to add a new column with the seasons. Basically, I want to say that if the date was made between December and February, then the corresponding season would be winter. I have tried the following, but it gives me: "Error: Not compatible with requested type: [type=character; target=double]."

 df$season = ifelse(between(df$date,"2018-11-30", "2019-03-01"), "Invierno"
ifelse(between(df$date,"2019-02-28", "2019-06-01"),"Spring", ifelse(between(df$date,"2019-06-30", "2019-07-01"),"Summer",
"Fall")))

Does this mean I have to reformat the date to character or is there any way I could create the seasons column using the date format?

Thanks in advance!

1 Answers

Two things happening here. First you need to tell R that you want a date string to actually be a date using as.Date. But then once that vector is a date, you can't use ifelse anymore because that (very useful!) function doesn't play well with dates. So it is a good opportunity to introduce dplyr's case_when syntax which accomplishes the same thing but in a more readable way:

library(dplyr, warn.conflicts = FALSE)
date <- c("2019-06-01","2019-07-01","2019-10-01","2019-10-01","2019-09-01","2019-04-01","2019-04-01","2019-04-01","2019-04-01",
"2019-04-01","2018-08-01","2018-08-01","2018-08-01","2018-07-01","2018-08-01","2018-07-01","2018-07-01","2018-06-01")


df <- data.frame(date)

## first need to tell R that date is actually a date
df$date <- as.Date(df$date)

## Turns out that ifelse doesn't actually work well for dates so I'll introduce the glorious case_when function
df$season <- case_when(
  between(df$date, as.Date("2018-11-30"), as.Date("2019-03-01")) ~ "Invierno",
  between(df$date, as.Date("2019-02-28"), as.Date("2019-06-01")) ~ "Spring",
  between(df$date, as.Date("2019-06-30"), as.Date("2019-07-01")) ~ "Summer",
  TRUE ~ "Fall"
)

df
#>          date season
#> 1  2019-06-01 Spring
#> 2  2019-07-01 Summer
#> 3  2019-10-01   Fall
#> 4  2019-10-01   Fall
#> 5  2019-09-01   Fall
#> 6  2019-04-01 Spring
#> 7  2019-04-01 Spring
#> 8  2019-04-01 Spring
#> 9  2019-04-01 Spring
#> 10 2019-04-01 Spring
#> 11 2018-08-01   Fall
#> 12 2018-08-01   Fall
#> 13 2018-08-01   Fall
#> 14 2018-07-01   Fall
#> 15 2018-08-01   Fall
#> 16 2018-07-01   Fall
#> 17 2018-07-01   Fall
#> 18 2018-06-01   Fall

Created on 2020-05-29 by the reprex package (v0.3.0)

Related