Сохранить порядок после форматирования даты в символьном векторе - PullRequest
0 голосов
/ 17 марта 2020

Я хочу сделать частотный график дат в кадре данных. График должен быть граненым для года, а даты должны отображаться в формате «01 апреля».

Здесь могут быть данные

x = as.POSIXct(c("2018-04-01", "2018-04-15", "2018-05-01", "2018-05-15",
      "2019-04-01", "2019-04-15", "2019-05-01", "2019-05-15"))

df = data.frame(date = sample(x,30, replace = TRUE))
df$year <-  format(df$date, "%Y")

Если я создаю граненый график с исходной датой переменная, оба графика не совпадают, потому что весь диапазон дат отображается на оси х. Однако я хочу сопоставить информацию о дне и месяце.

library (ggplot2)

ggplot(df, aes(x=as.Date(date), y = ..count..)) + 
  geom_bar() +
  facet_grid(year ~ ., scales = "free_x") + 
  scale_x_date(date_breaks = "weeks" , date_labels = "%b-%d") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

enter image description here

Теперь я создаю символьный вектор, сохраняя информацию о дне и месяце. Это нормально, но формат даты не очень приятный.

df$date_working <- format(df$date, "%m-%d")

ggplot(df, aes(x=date_working, y = ..count..)) + 
  geom_bar() +
  facet_grid(year ~ ., scales = "free_x") +
  labs(title="right order")

enter image description here

Поэтому я создаю другую переменную даты. Однако проблема в том, что эта переменная не поддерживает правильный порядок.

df$date_appreciated <- format(df$date, "%d %b")

ggplot(df, aes(x=date_appreciated, y = ..count..)) + 
  geom_bar() +
  facet_grid(year ~ ., scales = "free_x") +
  labs(title="wrong order")

enter image description here

У кого-нибудь есть решение? Мне нужно создать переменную date_appreciated, сохраняя порядок переменной date_working.

1 Ответ

1 голос
/ 17 марта 2020

Вы можете легко получить это, отформатировав столбец date_working как факторную переменную, используя пакет {forcats} (этот пакет включен как часть {tidyverse}.

В отличие от base::as.factor() который автоматически создает уровни факторов на основе алфавитной сортировки базовой переменной, forcats::as_factor() по умолчанию создает уровни на основе текущего порядка сортировки данных, что позволяет генерировать «красиво отформатированные» метки даты, сохраняя правильный порядок сортировки:

# load required libraries
library(tidyverse)

# your original code
x = as.POSIXct(c("2018-04-01", "2018-04-15", "2018-05-01", "2018-05-15",
                 "2019-04-01", "2019-04-15", "2019-05-01", "2019-05-15"))

df = data.frame(date = sample(x,30, replace = TRUE))
df$year <-  format(df$date, "%Y")

# sort df by date using dplyr::arrange %>% create a new column called
# date_working which is equal to the date column, but with"nicer" formatting and
# then convert the column  to factor using forcats::as_factor date factor
# version of date variable that is sorted appropriately using forcats
df <- df %>% 
  arrange(date) %>% 
  mutate(date_working = format(date, "%d %b") %>% forcats::as_factor())

# generate the plot output as before, except now it should be ordered correctly
ggplot(df, aes(x=date_working, y = ..count..)) + 
  geom_bar() +
  facet_grid(year ~ ., scales = "free_x") +
  labs(title="right order")

enter image description here

На самом деле, если бы вы хотели, вы могли бы создать это форматирование «на лету» во время вызова ggplot. Следующий код чанк должен дать тот же график, что показан выше:

df %>% 
  arrange(date) %>% 
  ggplot(aes(x = format(date, "%d %b") %>% forcats::as_factor(), y = ..count..)) + 
  geom_bar() +
  facet_grid(year ~ ., scales = "free_x") +
  labs(title="right order")
...