简体   繁体   English

将因子转换为日期(年月)

[英]Convert Factor to Date (Year-Month)

My data column looks like... 我的资料栏看起来像...

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

Just wondering how to turn this into a date, because when I punch this code in I get NA's 只是想知道如何将其转换为日期,因为当我在此代码中打孔时,会得到NA

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

date
<fctr>
NA
NA
NA
NA

Thanks for the help! 谢谢您的帮助!

The OP has requested to convert Year-Mon (without day of the month) to Date from a data.frame column which is a factor. OP已请求将data-frame列中的Year-Mon(每月的无日)转换为Date,这是一个因素。 Without day of the month, the date is incomplete which produces NA s. 如果没有月份,则日期是不完整的,会产生NA

There are various options available to deal with incomplete dates. 有多种选项可用于处理不完整的日期。

as.Date() with day of the month supplemented as.Date()并补充每月的某天

As suggested in a similar form by db : db所建议的类似形式:

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

lubridate::ymd()

The ymd() function of the lubridate package has a truncated parameter to parse incomplete dates: lubridate软件包的ymd()函数具有一个truncated参数来解析不完整的日期:

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

Note that lubridate automatically has assumed the first day of each month. 请注意, lubridate自动假定为每月的第一天。

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

The option to use the as.yearmon() function from the zoo package has already been suggested by Sagar and statoptim . Sagarstatoptim已经建议使用zoo包中的as.yearmon()函数。

The answer of Sagan is incomplete because as.yearmon() returns an object of class yearmon but not Date : Sagan的答案是不完整的,因为as.yearmon()返回的类为yearmon但不是Date的对象:

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

The answer of statoptim is unnecessarily complicated as yearmon can directly be coerced to Date : 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"

Note that we have to use zoo::as.Date() if we haven't loaded zoo beforehand because base R's as.Date() doesn't know how to handle yearmon objects. 请注意,如果我们尚未预先加载zoo ,则必须使用zoo::as.Date() ,因为基数R的as.Date()不知道如何处理yearmon对象。

zoo::as.Date() has automatically assumed the first day of each month by default. zoo::as.Date()默认自动设置为每月的第一天。 The frac parameter can be used to control which day of the month is returned, eg, 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"

returns the last day of each month. 返回每个月的最后一天。

Caveat 警告

It might be the case that the current locale may influence the interpretation of the abbreviated month names (which might be the case in statoptim's answer ). 当前语言环境可能会影响缩写月份名称的解释(在statoptim的答案中可能就是这种情况)。

There's an answer to a related question which suggests to check out the examples section of ?as.Date : 一个相关问题的答案 ,建议您查看?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

Following will work. 以下将起作用。

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

The zoo package documentation has the following example that also returns NA on my R zoo软件包文档包含以下示例,该示例在我的R上也返回NA

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

I am using gsub to replace "Jan" to "01". 我正在使用gsub将“ Jan”替换为“ 01”。 I see this is not the most efficient code but hope this helps you for now. 我看到这不是最有效的代码,但希望它现在对您有帮助。

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"
  • update / comment since I don't have enough reputation to leave comments to Uwe Block 's answer. 更新/评论,因为我没有足够的声誉来对Uwe Block的答案发表评论。 I found that "%b" (or passing month as abbreviation) does not work on my machine that have other language as operating system language. 我发现“%b”(或超过一个月的缩写)在使用其他语言作为操作系统语言的计算机上不起作用。 It works on another computer that has English as OS language. 它可以在另一台以英语作为OS语言的计算机上工作。 I do think question was posted because of the language issue. 我确实是因为语言问题而发布了问题。 I was suggesting to convert to numeric values of month to bypass language issue not because of conversion to base date object. 我建议将其转换为月份的数值以绕过语言问题,而不是因为转换为基准日期对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM