CalendR Dates and Gradients based on df

Hello Everyone,

Thank you in advance for your help it is much appreciated.
I am currently using the CalendR package to create a year calendar and a calendar for each month.

I have the following data frame example:

'''

 team <- c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A")
 opponent <- c("B", "C", "D", "B", "D", "C", "D", B", "B", "D")
 opponentHA <- c("@B", "C", "@D", "@B", "@D", "C", "D", B", "@B", "D")
 dayofyear <-  c(16, 69, 69, 88, 103, 121, 154, 176, 182, 202) 
  ###this is the day of year with October 1, 2021 set as Day 1
 ranking <- c(-3, 2, 2, -1, 0, 3, 0, -3, 2, 1)

 df  <- data.frame(dayofyear, team, opponent, opponentHA, ranking)

'''

Using CalendR I would like a yearly calendar from October 1, 2021 to March 31, 2022 where each of the dates in the df is

  1. indicated with a red to green color gradient (ranking = -3 (red), ranking = 3 (green))

This goal has caused me some trouble primarily due to difficulties adding a gradient based on the df$ranking values associated with each date.

My calendR code is below:

'''

 calendR(start_date = "2021-10-01",
    end_date = "2022-04-30",
    start = "M",               
    mbg.col = 1,           
    months.col = "white",      
    special.days = df$dayofyear, 
    gradient = TRUE,
    special.col = "#0A8007", # Color highest value special day = green
    low.col = "red",
    lty = 0,               
    weeknames = c("Mo", "Tu",  "We", "Th", "Fr", "Sa", "Su"),
    title = "Oct - May 2021",
    subtitle = "Gradient Based on Ranking",
    title.size = 40, 
    subtitle.size = 20,
    orientation = "l")

'''

from this code I receive an error stating that
"Error in calendR(start_date = "2021-10-01", end_date = "2022-04-30", start = "M", :
If gradient = TRUE, the length of 'special.days' must be the same as the number of days of the corresponding month or year"

Based on this error, this is extremely inconvenient considering I would like to apply a gradient to individual dates not every date on the calendar. Is there a better alternative to CalendR keeping in mind that I need this calendar to be very visually appealing.

Thank you very much for you help! It is much appreciated. I look forward to chatting with you.

Hi @zmcclean,
I don't think it's possible to use a colour gradient (or multiple pre-defined colours) to colour only the "special days" using the calendR package. You could ask the package maintainer for help, or lodge a new feature request. See the output from maintainer("calendR").
Also, note that some double quotes are missing from the code you posted.

Maybe this alternative package would help:
https://www.infoworld.com/article/3331605/how-to-create-color-coded-calendars-in-r.html

1 Like

Thank you for your help on this. It is too bad that this package does not allow for this feature. I will follow your recommendations!

Hi! I am the author of the package. I saw this question on Twitter. The GitHub repository of the package contains lots of examples of different scenarios: https://github.com/R-CoderDotCom/calendR

Achieving what you want was possible but only with one color for the gradient. I had to fix only one line of code to allow two colors. Please install the latest GitHub version of the package and run the following code:

library(calendR)

team <- c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A")
opponent <- c("B", "C", "D", "B", "D", "C", "D", "B", "B", "D")

opponentHA <- c("@B", "C", "@D", "@B", "@D", "C", "D","B", "@B", "D")
dayofyear <-  c(16, 69, 69, 88, 103, 121, 154, 176, 182, 202) 
###this is the day of year with October 1, 2021 set as Day 1
ranking <- c(-3, 2, 2, -1, 0, 3, 0, -3, 2, 1)

df  <- data.frame(dayofyear, team, opponent, opponentHA, ranking)

from <- "2021-10-01"
to <- "2022-04-30"

as.Date(to)-as.Date(from) # 211 (+ 1)

# Set all as NA (NA values will be colored with white)
days <- rep(NA, 212)

# Pass you data to the corresponding days
days[df$dayofyear] <- df$ranking

calendR(from = "2021-10-01",
        to = "2022-04-30",
        start = "M",               
        mbg.col = 1,           
        months.col = "white",      
        special.days = days, 
        gradient = TRUE,
        special.col = "#0A8007", # Color highest value special day = green
        low.col = "red",
        lty = 0,               
        weeknames = c("Mo", "Tu",  "We", "Th", "Fr", "Sa", "Su"),
        title = "Oct - May 2021",
        subtitle = "Gradient Based on Ranking",
        title.size = 40, 
        subtitle.size = 20,
        orientation = "l")

The previous code will result into:

I think this is what you wanted to achieve. The calendR package is very flexible, but sometimes hard to understand.

Best regards,
José Carlos

2 Likes

Both are possible to achieve. Check the examples of the GitHub repository, for instance:

# Vector of NA which length is the number of days of the year or month
myfills <- rep(NA, 366)

# Add the events to the desired days
myfills[c(1:4, 50, 300:315)] <- "Holidays"
myfills[16] <- "Birthday"

calendR(special.days = myfills,
        special.col = 2:3,     # Add as many colors as events
        legend.pos = "right")  # Add a legend if desired

1 Like

Thank you very much for putting the time and effort into making this change for me. Your skills and knowledge are much appreciated

Hello José ,

Once again, thank you for your help. I have updated calendR and have ran the code in the way you have provided (thank you for this). However, I still run get the following error response.

Error in if (any(special.days > length(dates))) { :
missing value where TRUE/FALSE needed

Do you have any recommendations on how to avoid this error? Thank you for your time. I appreciate your help on the matter.

HI!

I can't reproduce your issue:

Make sure you have updated the package correctly. I usually use detach(package:calendR, unload = TRUE) and remove.packages("calendR") before installing and loading the newest version.

Your error is familiar to me, but I don't remember in which scenario I faced it. Today I also added a new argument named ncol, so to check if the function you are using is up to date checking if that argument exists.

Thank you for the help with this. It turns out that removing the package and then installing it worked and your solution is perfect. Thanks a lot for the help.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.