Объект Date дает ошибки в ggplot2 и dplyr после использования melt

Я столкнулся с ошибкой с фасетированием ggplot2 и dplyr group_by при использовании фрейма данных с переменной даты. Эта ошибка возникает только в том случае, если я сначала конвертирую переменную даты, а затем расплавляю фрейм данных. Если я сделаю наоборот, переменная будет точно такой же, но не выдаст ошибки. Пример:

#base df
df <- data.frame(
id = c("A", "B", "C"),
date1 = c("12/Sep/2010", "13/Mar/2011", "05/Jan/2010"),
date2 = c("13/Sep/2010", "14/Mar/2011", "06/Jan/2010"),
value1 = 1:3,
value2 = 4:6
)

df
id       date1       date2 value1 value2
1  A 12/Sep/2010 13/Sep/2010      1      4
2  B 13/Mar/2011 14/Mar/2011      2      5
3  C 05/Jan/2010 06/Jan/2010      3      6

Я покажу пример с mutate, но использование df $ date ‹- as.Date (df $ date) дает ту же ошибку. Прошу прощения или уродливый и неэффективный код для очистки моих данных (предложения приветствуются :-)).

#mutate first
df_muta <- df %>% mutate_each(funs(as.Date(., format = "%d/%b/%Y")), c(starts_with("date")))
df_muta <- data.frame(
  id = melt(df_muta, id.vars = c("id"), measure.vars = c("date1", "date2"))[[1]],
  date = melt(df_muta, id.vars = c("id"), measure.vars = c("date1", "date2"))[[3]],
  value = melt(df_muta, id.vars = c("id"), measure.vars = c("value1", "value2"))[[3]])

str(df_muta)
'data.frame':  6 obs. of  3 variables:
  $ id   : Factor w/ 3 levels "A","B","C": 1 2 3 1 2 3
  $ date : Date, format: "2010-09-12" "2011-03-13" "2010-01-05" ...
  $ value: int  1 2 3 4 5 6

p <- ggplot(df_muta, aes(x = date, y = value)) + geom_point()

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

p + facet_wrap( ~ id)

И если я попытаюсь использовать dplyr group_by, это тоже приведет к ошибке.

df_muta %>% group_by(id)
Error: column 'date' has unsupported type

Итак, я попробовал сначала растопить, а затем преобразовать дату.

df_melt <- data.frame(
  id = melt(df, id.vars = c("id"), measure.vars = c("date1", "date2"))[[1]],
  date = melt(df, id.vars = c("id"), measure.vars = c("date1", "date2"))[[3]],
  value = melt(df, id.vars = c("id"), measure.vars = c("value1", "value2"))[[3]])
df_melt <- df_melt %>% mutate(date = as.Date(date, format = "%d/%b/%Y"))

str(df_melt)
'data.frame':  6 obs. of  3 variables:
  $ id   : Factor w/ 3 levels "A","B","C": 1 2 3 1 2 3
  $ date : Date, format: "2010-09-12" "2011-03-13" "2010-01-05" ...
  $ value: int  1 2 3 4 5 6

Структура и значения обоих фреймов данных кажутся точно такими же, но последний не даст никаких ошибок с осью графика фасета или group_by. Это ошибка? В чем разница между объектами даты?

Спасибо!


person JG11235    schedule 28.08.2014    source источник


Ответы (1)


Я думаю, вот что происходит.

df_muta <- df %>% mutate_each(funs(as.Date(., format = "%d/%b/%Y")), c(starts_with("date")))

#> df_muta
#  id      date1      date2 value1 value2
#1  A 2010-09-12 2010-09-13      1      4
#2  B 2011-03-13 2011-03-14      2      5
#3  C 2010-01-05 2010-01-06      3      6

#> df_muta$date1
#[1] "2010-09-12" "2011-03-13" "2010-01-05"

#> unclass(df_muta$date1)
#[1] 14864 15046 14614

Здесь вы видите даты.

df_muta <- data.frame(
    id = melt(df_muta, id.vars = c("id"), measure.vars = c("date1", "date2"))[[1]],
    date = melt(df_muta, id.vars = c("id"), measure.vars = c("date1", "date2"))[[3]],
    value = melt(df_muta, id.vars = c("id"), measure.vars = c("value1", "value2"))[[3]])

Я запустил date = melt(df_muta, id.vars = c("id"), measure.vars = c("date1", "date2"))[[3]] и посмотрел, что вернет R. Вот результаты.

#> date = melt(df_muta, id.vars = c("id"), measure.vars = c("date1", "date2"))[[3]]
#> date
#[1] 14864 15046 14614 14865 15047 14615
#attr(,"class")
#[1] "Date"

#> unclass(date)
#[1] 14864 15046 14614 14865 15047 14615
#attr(,"class")
#[1] "Date"

Класс по-прежнему Date, но вы видите числа. Теперь позвольте мне расположить данные по-другому. В этом посте я использовал исходный df. Но я не использовал здесь melt().

df$date1 <- as.Date(df$date1,format = "%d/%b/%Y")
df$date2 <- as.Date(df$date2,format = "%d/%b/%Y")

id <- rep(c("A", "B", "C"), each = 1, times = 2)
dates <- c(df$date1, df$date2)
values <-c(df$value1, df$value2)

foo <- data.frame(id, dates, values)

Затем я проверил даты foo $

#> foo$dates
#[1] "2010-09-12" "2011-03-13" "2010-01-05" "2010-09-13" "2011-03-14" "2010-01-06"

#> unclass(foo$dates)
#[1] 14864 15046 14614 14865 15047 14615

У меня здесь свидания.

Когда вы рисуете ggplot с помощью df_muta, вы можете каким-то образом нарисовать одну фигуру, хотя df_muta $ date на самом деле не является датой. Но когда вы добавляете facet_wrap, ваша дата df_muta $ не работает для ggplot. Это потому, что ggplot не думает, что у вас есть свидание. Он думает, что у вас есть числа.

Если я использую foo, у меня нет проблем со следующим.

p <- ggplot(foo, aes(x = dates, y = values)) + 
         geom_point() +
         facet_wrap( ~ id)

p

Остался еще один вопрос, связанный с вашим df_melt. Когда я запускал ваш скрипт, у меня появлялись сообщения об ошибках.

#> df_melt <- data.frame(
#+   id = melt(df, id.vars = c("id"), measure.vars = c("date1", "date2"))[[1]],
#+   date = melt(df, id.vars = c("id"), measure.vars = c("date1", "date2"))[[3]],
#+   value = melt(df, id.vars = c("id"), measure.vars = c("value1", "value2"))[[3]])
#Warning messages:
#1: attributes are not identical across measure variables; they will be dropped 
#2: attributes are not identical across measure variables; they will be dropped 
#> df_melt <- df_melt %>% mutate(date = as.Date(date, format = "%d/%b/%Y"))

Опять же, я сосредоточился на вашей части даты в первом df_melt

#> date = melt(df, id.vars = c("id"), measure.vars = c("date1", "date2"))[[3]]
#Warning message:
#attributes are not identical across measure variables; they will be dropped 

Но когда я проверил второй df_melt, R вернул следующее.

#> df_melt$date
#[1] "2010-09-12" "2011-03-13" "2010-01-05" "2010-09-13" "2011-03-14" "2010-01-06"

#> unclass(df_melt$date)
#[1] 14864 15046 14614 14865 15047 14615

У вас есть дата в df_melt $ date, тогда как у вас есть числа в качестве даты в df_muta $ date. Эти числа должны появиться в неклассе. Я не уверен, почему это произошло. Я бы порекомендовал вам не использовать расплав так, как вы его использовали. Вы видите, что R изменил дату на числа в df_muta. Точно так же вы видите предупреждения о возврате R в df_melt. Короче говоря, я считаю, что то, как вы использовали melt(), дало вам забавные результаты. Надеюсь, это расследование вам поможет.

person jazzurro    schedule 29.08.2014