【问题标题】:Convert Factor to Date (Year-Month)将因子转换为日期(年月)
【发布时间】:2017-08-08 18:32:30
【问题描述】:

我的数据列看起来像...

date
<fctr>
14-Jan
14-Feb
14-Mar
15-Jan

只是想知道如何将其转换为日期,因为当我输入此代码时,我得到了 NA's

hand$date <- as.Date(hand$date, format = "%y-%b")

date
<fctr>
NA
NA
NA
NA

感谢您的帮助!

【问题讨论】:

  • 也许library(zoo); as.Date(as.yearmon("15-Jan", "%y-%b"))
  • 使用了上面的两个代码,它只是重复相同的日期(2014-01-01)

标签: r date dplyr


【解决方案1】:

OP 已请求将 Year-Mon(没有月份中的某一天)从 data.frame 列转换为 Date,这是一个因素。如果没有日期,则日期不完整,会产生NAs。

有多种选项可用于处理不完整的日期。

as.Date() 补充了月份中的某天

正如d.b 以类似形式建议的那样:

as.Date(paste0(hand$date, "-01"), "%y-%b-%d")
#[1] "2014-01-01" "2014-02-01" "2014-03-01" "2015-01-01"

lubridate::ymd()

lubridate 包的ymd() 函数有一个truncated 参数来解析不完整的日期:

lubridate::ymd(hand$date, truncated = 1L)
#[1] "2014-01-01" "2014-02-01" "2014-03-01" "2015-01-01"

请注意,lubridate 自动假定为每个月的第一天。

zoo::as.yearmon()zoo::as.Date()

Sagarstatoptim 已经建议使用zoo 包中的as.yearmon() 函数的选项。

Sagan 的答案不完整,因为 as.yearmon() 返回的是 yearmon 类的对象,而不是 Date

str(zoo::as.yearmon(hand$date, "%y-%b"))
#Class 'yearmon'  num [1:4] 2014 2014 2014 2015

statoptim 的答案过于复杂,因为yearmon 可以直接强制转换为Date

zoo::as.Date(zoo::as.yearmon(hand$date, "%y-%b"))
#[1] "2014-01-01" "2014-02-01" "2014-03-01" "2015-01-01"

请注意,如果我们没有预先加载zoo,我们必须使用zoo::as.Date(),因为base R 的as.Date() 不知道如何处理yearmon 对象。

zoo::as.Date() 默认自动假定为每个月的第一天。 frac 参数可用于控制返回月份中的哪一天,例如,

zoo::as.Date(zoo::as.yearmon(hand$date, "%y-%b"), frac = 1)
#[1] "2014-01-31" "2014-02-28" "2014-03-31" "2015-01-31"

返回每个月的最后一天。

警告

当前语言环境可能会影响对缩写月份名称的解释(statoptim's answer 中可能就是这种情况)。

There's an answer 到一个相关问题,建议查看?as.Date 的示例部分:

## read in date info in format 'ddmmmyyyy'
## This will give NA(s) in some locales; setting the C locale
## as in the commented lines will overcome this on most systems.
## lct <- Sys.getlocale("LC_TIME"); Sys.setlocale("LC_TIME", "C")
x <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960")
z <- as.Date(x, "%d%b%Y")
## Sys.setlocale("LC_TIME", lct)
z

【讨论】:

    【解决方案2】:

    以下将起作用。

    > library(zoo)
    > as.yearmon("14-Jan", "%y-%b")
    [1] "Jan 2014"
    

    【讨论】:

      【解决方案3】:

      zoo 包文档有以下示例,它在我的 R 上也返回 NA

      zoo::as.yearmon("mar07", "%b%y")
      

      我正在使用 gsub 将“Jan”替换为“01”。我发现这不是最有效的代码,但希望现在对您有所帮助。

      library(zoo)
      df = data.frame(date = c("14-Jan", "14-Feb", "15-Jan"), stringsAsFactors = F)
      
      month.abb
      # [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" ....
      
      month.num = substr( paste0("0", c(1:12)), start=c(rep(1,9), rep(2,3)), stop=3)
      head(month.num)
      # [1] "01" "02" "03" "04" "05" "06"
      
      # can't think of or find ways to vectorize gsub 
      for(i in 1:12) {
        df$date = gsub(df$date, pattern=month.abb[i], replacement=month.num[i])
      }
      
      as.Date(as.yearmon(df$date, format = "%y-%m"))
      # [1] "2014-01-01" "2014-02-01" "2015-01-01"
      
      • 更新/评论,因为我没有足够的声誉将 cmets 留给 Uwe Block 的答案。我发现“%b”(或将月份作为缩写)在我的机器上无法使用其他语言作为操作系统语言。它可以在另一台以英语作为操作系统语言的计算机上运行。我确实认为问题是由于语言问题而发布的。我建议转换为月份的数值以绕过语言问题,而不是因为转换为基本日期对象。

      【讨论】:

      • 感谢您指出当前语言环境的潜在问题。我在回答中添加了一个警告。您可能会在对您的案例有用的相关问题上找到此 answer
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      • 1970-01-01
      相关资源
      最近更新 更多