【问题标题】:Date object giving errors in ggplot2 and dplyr, after using melt使用融化后,日期对象在 ggplot2 和 dplyr 中出现错误
【发布时间】:2014-10-22 22:36:03
【问题描述】:

在使用带有日期变量的数据框时,我遇到了 ggplot2 faceting 和 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

#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 方面出现任何错误。它是一个错误吗?日期对象的区别在哪里?

谢谢!

【问题讨论】:

    标签: r date ggplot2 dplyr melt


    【解决方案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"
    

    Class 仍然是 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$dates

    #> 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
    

    我在这里有约会。

    当您使用 df_muta 绘制 ggplot 时,您可以以某种方式绘制单个图形,尽管 df_muta$date 并不是真正的日期。但是,当您添加 facet_wrap 时,您的 df_muta$date 不适用于 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 中有数字作为日期。这些数字应该出现在 unclass 中。我不确定为什么会这样。我会推荐的一件事是你可能不想以你使用的方式使用融化。您会看到 R 将日期更改为 df_muta 中的数字。同样,您会在 df_melt 中看到 R 重新返回警告。总之,我相信你使用melt() 的方式给了你有趣的结果。希望本次调查对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2020-09-19
      • 1970-01-01
      • 2012-05-21
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多