scale_x_date возвращает ошибку: как я могу применить временные рамки к оси x?

#r #date #ggplot2 #plot #axis

Вопрос:

Я сравниваю частоту острых хирургических вмешательств за неделю до и во время пандемии Covid-19. У меня есть простая линейная регрессия, в которой каждое наблюдение соответствует неделе и представлено в lin.model$cons_week . Имеется 221 наблюдение, соответствующее 221 последовательной неделе с момента 2017-01-02 (первый понедельник 2017 года) и до 2021-04-05

 mod <- fortify(lm(n ~ cons_week * corona, data = lin.model))
 

С n указанием количества хирургических процедур и corona указывает, к какому периоду времени cons_week относится.

У меня есть

 mod %>%
  ggplot(aes(y = .cooksd))  
  geom_col(data = filter(mod, corona == "Normal") %>% droplevels(),
           aes(seq_along(.cooksd)),
           color = "#6DBCC3", fill = alpha("#6DBCC3", .2))   
  geom_col(data = filter(mod, corona == "C19") %>% droplevels(),
           aes(seq_along(.cooksd) 167),
           color = "#8B3A62", fill = alpha("#8B3A62", .2))   
  geom_hline(yintercept = 4/nrow(lin.model), col = "black", lty = 2)  
  geom_vline(xintercept = 167, color = "red", lty = 2)  
  scale_y_continuous(name = "Cook's Distance")
 

Дающий

введите описание изображения здесь

Тем не менее, я хотел x-axis бы показать какую-то разумную временную линию, поскольку каждое наблюдение Cook's соответствует одной неделе.

введите описание изображения здесь

Я пытался scale_date_x() :

 mod %>%
  mutate(cons_week_dt = as.Date("2017-01-02")   cons_week*7) %>%
  ggplot(aes(x = cons_week_dt, y = .cooksd))  
  geom_col(data = filter(mod, corona == "Normal") %>% droplevels(),
           aes(seq_along(.cooksd)),
           color = "#6DBCC3", fill = alpha("#6DBCC3", .2))   
  geom_col(data = filter(mod, corona == "C19") %>% droplevels(),
           aes(seq_along(.cooksd) 167),
           color = "#8B3A62", fill = alpha("#8B3A62", .2))   
  geom_hline(yintercept = 4/nrow(lin.model), col = "black", lty = 2)  
  geom_vline(xintercept = 167, color = "red", lty = 2)  
  scale_y_continuous(name = "Cook's Distance")   
  scale_x_date(name = "",
               date_breaks = "3 months", date_labels = "%B-%Y", expand = c(0.01, 0)) 
 

Но это возвращает ошибку:

Ошибка: Неверный ввод: date_trans работает только с объектами класса Date

 lin.model <- structure(list(corona = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L), .Label = c("Normal", "C19"), class = "factor"), cons_week = c(56, 
6, 150, 87, 16, 100, 16, 149, 62, 38, 74, 3, 80, 64, 72, 80, 
71, 25, 100, 159, 80, 72, 35, 14, 55, 162, 14, 4, 100, 34, 81, 
59, 156, 84, 165, 129, 70, 140, 113, 13, 65, 76, 33, 7, 93, 40, 
107, 72, 43, 123, 142, 65, 83, 119, 63, 116, 18, 48, 97, 6, 93, 
79, 81, 158, 8, 45, 143, 114, 83, 96, 26, 91, 113, 22, 54, 126, 
93, 39, 33, 132, 97, 126, 136, 145, 35, 30, 109, 160, 20, 74, 
162, 26, 112, 145, 28, 22, 28, 153, 131, 136, 209, 203, 188, 
180, 214, 180, 176, 203, 219, 172, 222, 212, 183, 200, 218, 208, 
198, 169, 210, 222, 207, 184, 175, 185, 198, 192, 206, 195, 219, 
193, 197, 217, 204, 193, 193, 182, 175, 169, 170, 208, 192, 181, 
186, 186, 209, 212, 200, 194, 213, 178, 213, 212, 209, 205, 183, 
206, 199, 181, 187, 174, 177, 215, 193, 207, 207, 204, 187, 195, 
174, 184, 171, 218, 188, 181, 197, 180, 208, 203, 192, 173, 218, 
173, 196, 185, 212, 201, 194, 221, 205, 210, 213, 174, 207, 181, 
189, 179, 200, 196, 216, 201), n = c(9L, 14L, 11L, 15L, 19L, 
12L, 19L, 20L, 12L, 17L, 9L, 13L, 7L, 6L, 12L, 7L, 11L, 15L, 
12L, 8L, 7L, 12L, 15L, 13L, 10L, 11L, 13L, 20L, 12L, 10L, 11L, 
11L, 16L, 17L, 13L, 12L, 15L, 6L, 13L, 14L, 14L, 16L, 25L, 15L, 
11L, 19L, 22L, 12L, 18L, 18L, 12L, 14L, 11L, 18L, 14L, 11L, 14L, 
14L, 15L, 14L, 11L, 15L, 11L, 15L, 16L, 14L, 11L, 12L, 11L, 18L, 
19L, 16L, 13L, 10L, 14L, 19L, 11L, 12L, 25L, 9L, 15L, 19L, 15L, 
19L, 15L, 17L, 11L, 11L, 17L, 9L, 11L, 19L, 16L, 19L, 17L, 10L, 
17L, 14L, 12L, 15L, 15L, 12L, 14L, 10L, 13L, 10L, 9L, 12L, 18L, 
15L, 20L, 17L, 13L, 10L, 14L, 13L, 17L, 15L, 14L, 20L, 16L, 10L, 
11L, 9L, 17L, 15L, 15L, 9L, 18L, 12L, 14L, 10L, 16L, 12L, 12L, 
16L, 11L, 15L, 8L, 13L, 15L, 13L, 19L, 19L, 15L, 17L, 10L, 8L, 
10L, 12L, 10L, 17L, 15L, 19L, 13L, 15L, 17L, 13L, 15L, 13L, 11L, 
16L, 12L, 16L, 16L, 16L, 15L, 9L, 13L, 10L, 11L, 14L, 14L, 13L, 
14L, 10L, 13L, 12L, 15L, 22L, 14L, 22L, 22L, 9L, 17L, 15L, 8L, 
9L, 19L, 14L, 10L, 13L, 16L, 13L, 12L, 15L, 10L, 22L, 14L, 15L
)), row.names = c(NA, -200L), groups = structure(list(corona = structure(1:2, .Label = c("Normal", 
"C19"), class = "factor"), .rows = structure(list(1:100, 101:200), ptype = integer(0), class = c("vctrs_list_of", 
"vctrs_vctr", "list"))), row.names = c(NA, -2L), class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))
 

Комментарии:

1. Если вы хотите использовать scale_x_date , ваша переменная x должна иметь класс «Дата». Все так просто. Я предлагаю вам создать переменную даты и использовать ее вместо seq_along(.cooksd) .

2. Я пытался сделать это с cons_week_dt помощью . Мои извинения, но, похоже, для меня это не так просто. Пожалуйста, не могли бы вы решить эту проблему? Вам это кажется довольно легким делом. Заранее большое вам спасибо.

Ответ №1:

Основная проблема с вашим кодом заключается в том, что вы сопоставлены seq_along(.cooksd) на x. Чтобы решить эту проблему, просто подготовьте свои данные в качестве отдельного шага, чтобы все слои использовали одни и те же данные. Также нет необходимости в подстановке и двух geom_col . Только один необходим при отображении вашего var corona на color и fill и настройке цветов с помощью scale_color/fill_manual

 library(ggplot2)
library(dplyr)

mod <- fortify(lm(n ~ cons_week * corona, data = lin.model))

mod1 <- mod %>%
  mutate(cons_week_dt = as.Date("2017-01-02")   cons_week*7)

cols <- c(Normal = "#6DBCC3", C19 = "#8B3A62")

ggplot(mod1, aes(x = cons_week_dt, y = .cooksd))  
  geom_col(aes(color = corona, fill = corona))   
  geom_hline(yintercept = 4/nrow(lin.model), col = "black", lty = 2)  
  geom_vline(xintercept = 167, color = "red", lty = 2)  
  scale_color_manual(values = cols)  
  scale_fill_manual(values = alpha(cols, .2))  
  scale_y_continuous(name = "Cook's Distance")   
  scale_x_date(name = "",
               date_breaks = "3 months", date_labels = "%B-%Y", expand = c(0.01, 0))  
  guides(color = "none", fill = "none")
 

Комментарии:

1. Спасибо тебе, Стефан. Есть ли какие-либо простые шаги для добавления geom_col в качестве легенды?

2. Хаха. Подумал, что он тебе не нужен, поэтому я удалил его через guides() . Удалите эту строку, и вы получите свою легенду