【问题标题】:Format Date to Year-Month in R在R中将日期格式化为年月
【发布时间】:2018-10-24 13:53:02
【问题描述】:

我想以年月格式保留我当前的日期列作为日期。它目前被转换为 chr 格式。我试过 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")

提前致谢!

【问题讨论】:

  • Date 类保存日期,所以您能做的最好的事情就是将每个日期设置为该月的第一天。如果您真的需要一年级课程,请参阅zoo::yearmon
  • 要遵循 alistaire 的建议(和惯例)将每个日期设置为每月的第一天,请在创建 df 后立即运行 df$Date &lt;- floor_date(as.Date(df$Date), 'month')
  • @alistaire:编辑我的帖子以反映我正在寻找的格式。 zoo::yearmon 实际上给了我月份的名称。
  • 这只是打印方法,它们是为保持一致性而构建的。如果您不喜欢显示格式,通常在最后组装演示图/表格/诸如此类的时候进行修复,此时您可以打印字符串。
  • @Ryan:很有帮助,谢谢!

标签: r lubridate


【解决方案1】:

你可以用 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包
  • 您真正需要的是library(zoo); transform(df, Date = as.yearmon(Date))
  • 我仍然很想知道会发生什么,在这里我无法安装包 - 我正在做一些研究,看看我的 R 在 Windows 机器上发生了什么 - install.packages(" zoo") 将包安装到 'C:/Users/j/Documents/R/win-library/3.4' (因为 'lib' 未指定)
  • @JoniHoppen:您可能需要先安装 tidyquant,因为它包含 zoo 包。
  • 我发现了问题,我有 2 个 Rstudio 实例正在运行,所以在关闭这两个实例后它最终解决了。感谢各位的支持。希望有很棒的代码!
【解决方案2】:

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 并显示警告消息:所有格式都未能通过。也许我错过了什么?
  • 您的日期变量是否与您的示例完全相同?即year-month-date?
  • 我让它工作了。在执行此操作之前,我没有确定日期。我可以使用相同的楼层函数按周对日期进行分组吗?我使用了 mutate(Date = floor_date(as_date(Date), "week")) 但我猜这是不正确的格式?
  • 请参阅lubridate docs 了解四舍五入的日期。
【解决方案3】:

您可以使用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)

【讨论】:

    猜你喜欢
    • 2014-03-21
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2021-12-11
    相关资源
    最近更新 更多