【问题标题】:How do I group my date variable into month/year in R?如何在 R 中将日期变量分组为月/年?
【发布时间】:2015-10-19 18:30:30
【问题描述】:

我有一个“日期”向量,其中包含 mm/dd/yyyy 格式的日期:

 head(Entered_Date,5)
[1] 1/5/1998 1/5/1998 1/5/1998 1/5/1998 1/5/1998

我正在尝试根据日期绘制频率变量,但我想按月或年对日期进行分组。就像现在一样,每天都有一个频率,但我想按月或年绘制频率。因此,1998 年 1 月 5 日的频率不是 1,1998 年 1 月 7 日是 1,1998 年 1 月 8 日是 3,我想将 1998 年的频率显示为 5。这是一个相对较大的数据集,日期从 1998 年到现在,我想找到一些自动化的方法来完成这项工作。

> dput(head(Entered_Date))
structure(c(260L, 260L, 260L, 260L, 260L, 260L), .Label = c("1/1/1998", 
"1/1/1999", "1/1/2001", "1/1/2002", "1/10/2000", "1/10/2001", 
"1/10/2002", "1/10/2003", "1/10/2005", "1/10/2006", "1/10/2007", 
"1/10/2008", "1/10/2011", "1/10/2012", "1/10/2013", "1/11/1999", 
"1/11/2000", "1/11/2001", "1/11/2002", "1/11/2005", "1/11/2006", 
"1/11/2008", "1/11/2010", "1/11/2011", "1/11/2012", "1/11/2013", 
"1/12/1998", "1/12/1999", "1/12/2001", "1/12/2004", "1/12/2005", ...

【问题讨论】:

  • 为确保结果可重现,请发布dput(head(Entered_Date))的输出
  • 看看as.yearmon 来自zoo 包。

标签: r


【解决方案1】:

lubridate 包中的 floor_date() 函数可以很好地完成此任务。

data %>% 
    group_by(month = lubridate::floor_date(date, "month")) %>%
    summarize(summary_variable = sum(value))

感谢 Roman Cheplyaka https://ro-che.info/articles/2017-02-22-group_by_month_r

查看更多关于如何使用该功能:https://lubridate.tidyverse.org/reference/round_date.html

【讨论】:

  • 这是最好的答案 - 我见过。将字段保留为与字符相对的日期几乎是不可能的
  • 我想是的。将日期作为字符不是一个好主意,尤其是数据量很大。
  • 太棒了!我想这直接相当于在 ORACLE/SQL 中执行TRUNC(to_date(a.wh_prces_dte), 'MON')
【解决方案2】:

这是使用dplyr 的示例。您只需在 format 语句中为月份 %m 或年份 %Y 使用相应的日期格式字符串。

set.seed(123)
df <- data.frame(date = seq.Date(from =as.Date("01/01/1998", "%d/%m/%Y"), 
                                 to=as.Date("01/01/2000", "%d/%m/%Y"), by="day"),
                 value = sample(seq(5), 731, replace = TRUE))

head(df)
        date value
1 1998-01-01     2
2 1998-01-02     4
3 1998-01-03     3
4 1998-01-04     5
5 1998-01-05     5
6 1998-01-06     1

library(dplyr)

df %>%
mutate(month = format(date, "%m"), year = format(date, "%Y")) %>%
group_by(month, year) %>%
summarise(total = sum(value))

Source: local data frame [25 x 3]
Groups: month [?]

   month  year total
   (chr) (chr) (int)
1     01  1998   105
2     01  1999    91
3     01  2000     3
4     02  1998    74
5     02  1999    77
6     03  1998    96
7     03  1999    86
8     04  1998    91
9     04  1999    95
10    05  1998    93
..   ...   ...   ...

【讨论】:

  • 一件事,我如何让月份显示为月份的名称而不是数字?
  • @Learning_R 您需要提供完整的可重现数据集。您的 dput 已被切断,因此我无法获取您的数据来重现此标签问题,而我的示例确实提供了名称。
  • @Learning_R,取一个子集并取其中的一个dput。确保您可以在子集上重现错误。
  • 另外,我需要按月/年,而不是所有年份的同一个月
  • 我总是用df %&gt;% mutate(date2 = format(date, "%Y-%m")) %&gt;% group_by(date2) %&gt;% summarise(total = sum(value)) 之类的东西
【解决方案3】:

只需添加到@cdeterman 答案,您可以使用lubridatedplyr 来简化此操作:

df <- data.frame(date = seq.Date(from =as.Date("01/01/1998", "%d/%m/%Y"), 
                                 to=as.Date("01/01/2000", "%d/%m/%Y"), by="day"),
                 value = sample(seq(5), 731, replace = TRUE))

library(dplyr)
library(lubridate)

df %>%
mutate(month = month(date), year = year(date)) %>%
group_by(month, year) %>%
summarise(total = sum(value))

【讨论】:

    【解决方案4】:

    也许您只需像这样在数据中添加一列:

    Year &lt;- format(as.Date(Entered_Date, "%d/%m/%Y"), "%Y")

    【讨论】:

    • 将括号前的最后一位更改为“%m/%Y”...?strptime 将为您提供所有这些日期格式选项的密钥。
    【解决方案5】:

    不需要dplyr。看?as.POSIXlt

    df$date<-as.POSIXlt(df$date)
    mon<-df$date$mon
    yr<-df$date$year
    monyr<-as.factor(paste(mon,yr,sep="/"))
    df$date<-monyr
    

    不需要使用ggplot2,但它很适合这种事情。

    c <- ggplot(df, aes(factor(date)))
    c + geom_bar()
    

    如果您想查看实际数字

    aggregate(. ~ date,data = df,FUN=length )
    df2<-aggregate(. ~ date,data = df,FUN=length )
    df2
        date value
    1   0/98    31
    2   0/99    31
    3   1/98    28
    4   1/99    28
    5  10/98    30
    6  10/99    30
    7  11/97     1
    8  11/98    31
    9  11/99    31
    10  2/98    31
    11  2/99    31
    12  3/98    30
    13  3/99    30
    14  4/98    31
    15  4/99    31
    16  5/98    30
    17  5/99    30
    18  6/98    31
    19  6/99    31
    20  7/98    31
    21  7/99    31
    22  8/98    30
    23  8/99    30
    24  9/98    31
    25  9/99    31
    

    【讨论】:

      【解决方案6】:

      使用 cut() 函数有一个超级简单的方法:

          list = as.Date(c("1998-5-2", "1993-4-16", "1998-5-10"))
          cut(list, breaks = "month")
      

      你会得到这个:

          [1] 1998-05-01 1993-04-01 1998-05-01
          62 Levels: 1993-04-01 1993-05-01 1993-06-01 1993-07-01 1993-08-01 ... 1998-05-01
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-24
        • 2021-12-16
        • 2015-05-05
        • 1970-01-01
        • 2020-08-15
        • 2017-07-13
        • 1970-01-01
        相关资源
        最近更新 更多