在R中将日期格式化为年月

16

我希望保留当前的日期列,以年-月格式为日期。目前它被转换为字符格式。我已经尝试了as_datetime,但它将所有值强制转换为NA。 我要寻找的格式是:"2017-01"

library(lubridate)
df<- data.frame(Date=c("2017-01-01","2017-01-02","2017-01-03","2017-01-04",
                       "2018-01-01","2018-01-02","2018-02-01","2018-03-02"),
            N=c(24,10,13,12,10,10,33,45))
df$Date <- as_datetime(df$Date)
df$Date <- ymd(df$Date)
df$Date <- strftime(df$Date,format="%Y-%m")

提前感谢!


2
Date类保存日期,因此最好的方法是将每个日期设置为该月的第一天。如果您真的需要一个年-月类,请参见zoo::yearmon - alistaire
按照alistaire的建议(和常见做法)将每个日期设置为该月的第一天,请在创建df后立即运行 df$Date <- floor_date(as.Date(df$Date), 'month') - IceCreamToucan
@alistaire:我编辑了我的帖子以反映我正在寻找的格式。zoo::yearmon实际上给了我月份名称。 - AM_123
1
这只是打印方法,旨在保持一致性。如果您不喜欢显示格式,则通常在组装演示图/表/等内容时修复它的时间就到了,此时您可以只打印字符串。 - alistaire
@Ryan:非常有帮助,谢谢! - AM_123
@alistaire:明白了,谢谢! - AM_123
3个回答

19

lubridate 只处理日期,而日期有天数。然而,正如 alistaire 所提到的,如果您想按月份工作,您可以将它们分成月份。

library(tidyverse)

df_month <-
  df %>%
  mutate(Date = floor_date(as_date(Date), "month"))
如果您想按月份聚合数据,只需使用group_by()summarize()函数即可。
df_month %>%
  group_by(Date) %>%
  summarize(N = sum(N)) %>%
  ungroup()

#> # A tibble: 4 x 2
#>  Date           N
#>  <date>     <dbl>
#>1 2017-01-01    59
#>2 2018-01-01    20
#>3 2018-02-01    33
#>4 2018-03-01    45

这将强制所有日期值转换为NA,并显示警告消息:所有格式都未通过。也许我错过了什么? - AM_123
你的日期变量与示例中完全相同吗?也就是说,是 年-月-日 格式吗? - Mikael Poul Johannesson
我已经让它工作了。在执行之前,我没有将日期向下取整。我能否使用相同的floor函数按周分组我的日期?我使用了mutate(Date = floor_date(as_date(Date),“week”)),但猜测这是不正确的格式? - AM_123
1
请参考 lubridate 文档 来进行日期舍入。 - Mikael Poul Johannesson

5
您可以使用zoo::as.yearmon()函数来解决此问题。下面是解决方案:
library(tidyquant)
library(magrittr) 
library(dplyr)

df <- data.frame(Date=c("2017-01-01","2017-01-02","2017-01-03","2017-01-04",
                  "2018-01-01","2018-01-02","2018-02-01","2018-03-02"),
           N=c(24,10,13,12,10,10,33,45))
df %<>% mutate(Date = zoo::as.yearmon(Date))

是的,这不是必需的,但tidyquant会加载zoo包。 - Wlademir Ribeiro Prates
3
这里你只需要用 library(zoo); transform(df, Date = as.yearmon(Date)) 即可。 - G. Grothendieck
我仍然很好奇会发生什么事情,在这里我无法安装该软件包 - 我正在进行一些研究,以查看我的Windows机器上的R发生了什么 - install.packages("zoo") 将软件包安装到'C:/Users/j/Documents/R/win-library/3.4'中 (因为未指定“lib”) - Joni Hoppen
1
@JoniHoppen:你可能需要先安装 tidyquant,因为它包含了 zoo 包。 - AM_123
@AM_123 实际上在这种情况下不需要使用tidyquant,我们可以改用library('zoo'),代码也应该能正常工作。 - Wlademir Ribeiro Prates
1
我找到问题了,我运行了两个Rstudio实例,所以在关闭它们后最终解决了。感谢大家的支持。希望你们写出优秀的代码! - Joni Hoppen

2

您可以使用cut函数,并使用breaks="month"将日期中的所有天数转换为该月的第一天。因此,同一月份内的任何日期都将在新创建的列中具有相同的日期。

这对于按月份分组数据框中的所有其他变量非常有用(基本上就是您要做的事情)。但是,cut将创建一个因子,但这可以转换回日期。因此,您仍然可以在数据框中使用日期类。

您只是不能去掉日期中的日(因为那样就不是一个日期了...)。之后,您可以为轴或表格创建一个漂亮的格式。例如:

true_date <-
  as.POSIXlt(
    c(
      "2017-01-01",
      "2017-01-02",
      "2017-01-03",
      "2017-01-04",
      "2018-01-01",
      "2018-01-02",
      "2018-02-01",
      "2018-03-02"
    ),
    format = "%F"
  )

df <-
  data.frame(
    Date = cut(true_date, breaks = "month"),
    N = c(24, 10, 13, 12, 10, 10, 33, 45)
  )

## here df$Date is a 'factor'. You could use substr to create a formated column
df$formated_date <- substr(df$Date, start = 1, stop = 7)

## and you can convert back to date class. format = "%F", is ISO 8601 standard date format

df$true_date <- strptime(x = as.character(df$Date), format = "%F")

str(df)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接