Antonio
Antonio

Reputation: 1111

Adjust line in graph in R

The graph below generates a scatter plot based on date2. In addition, a horizontal line that refers to the mean is generated. Each day of the week has a different mean as you can see.

Note that in abline I specified h=mean_saturday, as 10/4 is a Saturday. But I didn't want to always have to change this part of the abline to show the right mean line, but my idea is to leave it automatically, that is, when I enter the date 10/4/2021 in the code, the code already recognize that the 10th it's Saturday and inserts the appropriate mean line. Any idea how to do this?

library(dplyr)
library(ggplot2)
library(tidyr)
library(lubridate)
library(tibble)
df <- structure(
  list(Id=c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
       date1 = c("2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20",
                 "2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20",
                 "2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20",
                 "2021-07-20","2021-07-20","2021-07-20","2021-07-20"),
       date2 = c("2021-07-01","2021-07-01","2021-07-01","2021-07-01","2021-04-02",
                 "2021-04-02","2021-04-02","2021-04-02","2021-04-02","2021-04-02","2021-04-03",
                 "2021-04-03","2021-04-03","2021-04-03","2021-04-03","2021-04-08","2021-04-08",
                 "2021-04-09","2021-04-09","2021-04-10","2021-04-10"),
       Week= c("Thursday","Thursday","Thursday","Thursday","Friday","Friday","Friday","Friday",
               "Friday","Friday","Saturday","Saturday","Saturday","Saturday","Saturday","Thursday",
               "Thursday","Friday","Friday","Saturday","Saturday"),
       D = c("","","Ho","","","","","","Ho","","","","","","","","","","","",""), 
       DR01 = c(2,1,4,3,3,4,1,6,3,7,2,3,4,6,7,8,4,2,6,2,3)),
  class = "data.frame", row.names = c(NA, -21L))

mean_thursday=4
mean_friday=5
mean_saturday=6


scatter_date <- function(dt, dta = df) {
  dta %>%
    filter(date2 == ymd(dt)) %>%
    summarize(across(starts_with("DR"), sum)) %>%
    pivot_longer(everything(), names_pattern = "DR(.+)", values_to = "val") %>%
    mutate(name = as.numeric(name)) %>%
    plot(xlab = "Days", ylab = "Types", xlim = c(0, 7),
         ylim = c((min(.$val) %/% 10) * 10, (max(.$val) %/% 10 + 1) * 15))
  abline(h=mean_saturday, col='blue') 
}  
scatter_date("2021-04-10",df)

enter image description here

Upvotes: 0

Views: 151

Answers (2)

Domingo
Domingo

Reputation: 671

You could try to convert the input date in your scatter_date function to a date and get the weekday: my_day <- weekdays(as.Date(dt)) add that to a switch statment for your means:

my_mean <- switch(
  my_day,
  "Saturday" = mean_saturday,
  "Friday" = mean_friday,
  "Thursday" = mean_thursday,
  0) # add here your other days

and replace mean_saturday in abline(h=mean_saturday, col='blue') with my_mean

here the full code:

library(dplyr)
library(ggplot2)
library(tidyr)
library(lubridate)
library(tibble)
df <- structure(
  list(Id=c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
       date1 = c("2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20",
                 "2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20",
                 "2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20","2021-07-20",
                 "2021-07-20","2021-07-20","2021-07-20","2021-07-20"),
       date2 = c("2021-07-01","2021-07-01","2021-07-01","2021-07-01","2021-04-02",
                 "2021-04-02","2021-04-02","2021-04-02","2021-04-02","2021-04-02","2021-04-03",
                 "2021-04-03","2021-04-03","2021-04-03","2021-04-03","2021-04-08","2021-04-08",
                 "2021-04-09","2021-04-09","2021-04-10","2021-04-10"),
       Week= c("Thursday","Thursday","Thursday","Thursday","Friday","Friday","Friday","Friday",
               "Friday","Friday","Saturday","Saturday","Saturday","Saturday","Saturday","Thursday",
               "Thursday","Friday","Friday","Saturday","Saturday"),
       D = c("","","Ho","","","","","","Ho","","","","","","","","","","","",""), 
       DR01 = c(2,1,4,3,3,4,1,6,3,7,2,3,4,6,7,8,4,2,6,2,3)),
  class = "data.frame", row.names = c(NA, -21L))

mean_thursday=4
mean_friday=5
mean_saturday=6


scatter_date <- function(dt, dta = df) {
  
  my_day <- weekdays(as.Date(dt))
  
  my_mean <- switch(
    my_day,
    "Saturday" = mean_saturday,
    "Friday" = mean_friday,
    "Thursday" = mean_thursday,
    0) # add here your other days
  
  dta %>%
    filter(date2 == ymd(dt)) %>%
    summarize(across(starts_with("DR"), sum)) %>%
    pivot_longer(everything(), names_pattern = "DR(.+)", values_to = "val") %>%
    mutate(name = as.numeric(name)) %>%
    plot(xlab = "Days", ylab = "Types", xlim = c(0, 7), main = paste0(my_day, ":", my_mean),
         ylim = c((min(.$val) %/% 10) * 10, (max(.$val) %/% 10 + 1) * 15))
  abline(h=my_mean, col='blue') 
}  
# testing the different means
scatter_date("2021-04-10",df)
scatter_date("2021-04-9",df)
scatter_date("2021-04-8",df)

Upvotes: 2

AlexB
AlexB

Reputation: 3269

One way would be to define a data.frame containing the mean for the days of interest and then use weekdays to extract the corresponding mean from that table.

Instead of

mean_thursday=4
mean_friday=5
mean_saturday=6

I would go for something like:

mean_df <- data.frame(mean = c(4:6),
                      day = c('Thursday', 'Friday', 'Saturday'))

and then

abline(h=subset(mean_df, day == weekdays(as.Date(dt)))$mean, col='blue')

which will be the only change in your function.

Upvotes: 1

Related Questions