从 zoo::yearmon 对象中提取月份和年份

Posted

技术标签:

【中文标题】从 zoo::yearmon 对象中提取月份和年份【英文标题】:Extract month and year from a zoo::yearmon object 【发布时间】:2012-04-02 17:22:38 【问题描述】:

我有一个yearmon 对象:

require(zoo)
date1 <- as.yearmon("Mar 2012", "%b %Y")
class(date1)
# [1] "yearmon"

如何从中提取月份和年份?

month1 <- fn(date1)
year1 <- fn(date1)

我应该用什么函数代替fn()

【问题讨论】:

【参考方案1】:

基于 cmets,结果应该是月份数(一月 = 1)和 4 位数的年份,因此假设我们刚刚运行了问题中的代码,我们有以下内容。除了问题中已经使用的之外,它不使用任何额外的包,非常短并且比任何其他解决方案都快得多(请参阅下面的基准部分)。

cycle(date1)
## [1] 3
as.integer(date1)
## [1] 2012

基准测试

在长度为 1000 的 yearmon 对象上,上述解决方案的速度比其他任何一年快 1000 倍,一个月快 200 倍。

library(zoo)
library(microbenchmark)
library(lubridate)

ym <- as.yearmon(rep(2000, 1000))

microbenchmark(
  as.integer(ym),
  as.numeric(format(ym, "%y")),
  as.POSIXlt(ym)$year + 1900,
  year(ym)
)

Unit: microseconds
                         expr     min       lq     mean   median       uq     max neval cld
               as.integer(ym)    18.2    27.90    28.93    29.15    31.15    51.2   100 a  
 as.numeric(format(ym, "%y")) 46515.8 47090.05 48122.28 47525.00 48080.25 69967.6   100   c
   as.POSIXlt(ym)$year + 1900 40874.4 41223.65 41798.60 41747.30 42171.25 44381.2   100  b 
                     year(ym) 40793.2 41167.70 42003.07 41742.40 42140.30 65203.3   100  b 
 
microbenchmark(
  cycle(ym),
  as.numeric(format(ym, "%m")),
  as.POSIXlt(ym)$mon + 1,
  month(ym)
)

Unit: microseconds
                         expr     min      lq      mean   median       uq     max neval cld
                    cycle(ym)   138.1   166.0   173.893   172.95   181.45   344.0   100 a  
 as.numeric(format(ym, "%m")) 46637.1 46954.8 47632.307 47325.90 47672.40 67690.1   100   c
       as.POSIXlt(ym)$mon + 1 40923.3 41339.1 41976.836 41689.95 42078.15 65786.4   100  b 
                    month(ym) 41056.4 41408.9 42082.975 41743.35 42164.95 66651.0   100  b 

【讨论】:

【参考方案2】:

从 1800 年到现在,我遇到过类似的数据问题,这对我有用:

data2$date=as.character(data2$date) 
lct <- Sys.getlocale("LC_TIME"); 
Sys.setlocale("LC_TIME","C")
data2$date<- as.Date(data2$date, format = "%Y %m %d") # and it works

【讨论】:

【参考方案3】:

对于大向量:

y = as.POSIXlt(date1)$year + 1900    # x$year : years since 1900
m = as.POSIXlt(date1)$mon + 1        # x$mon : 0–11

【讨论】:

这是最好的答案,因为 R 已经提供了方便的 POSIXlt 对象,这使得 zoo 包变得不必要 @Marco,这不是真的。它正在使用来自动物园的 as.POSIXlt.yearmon。【参考方案4】:

我知道 OP 在这里使用 zoo,但我发现这个线程在谷歌上搜索了相同问题的标准 ts 解决方案。所以我想我也会为ts 添加一个zoo-free 答案。

# create an example Date 
date_1 <- as.Date("1990-01-01")
# extract year
as.numeric(format(date_1, "%Y"))
# extract month
as.numeric(format(date_1, "%m"))

【讨论】:

如果与问题的输入一起使用,他使用来自动物园的 format.yearmon,因此它仅使用基本 R 是不正确的。 感谢您的澄清。看起来 S3 欺骗了我。【参考方案5】:

lubridate package 非常适合这种事情:

> require(lubridate)
> month(date1)
[1] 3
> year(date1)
[1] 2012

【讨论】:

谢谢你的回答。当您想要执行 if(year(date1) > 2014)year(date1) 之类的操作时,它尤其胜过其他解决方案 这绝对是我从 4000 份合同的开始日期中取出年份的要求的最佳答案。 @Ari B. Friedman 我目前正在使用 R 3.1.0 虽然这不支持 lubridate 包并尝试安装它并使用 year(date) 但它给出的是日期而不是年份仅适用于格式为“2015-05-06”的日期? @KRU 新版本的 R 有时需要几周的时间才能让存储库更新所有包。它应该适用于所有日期格式,只要它是真正的日期格式,而不是字符向量。如果仍然不能解决您的问题,并且您无法在 SO 中搜索问题的任何一个组成部分,请发布一个新的 q。【参考方案6】:

"yearmon" 类的对象使用format() 方法。这是您的示例日期(正确创建!)

date1 <- as.yearmon("Mar 2012", "%b %Y")

然后我们可以根据需要提取日期部分:

> format(date1, "%b") ## Month, char, abbreviated
[1] "Mar"
> format(date1, "%Y") ## Year with century
[1] "2012"
> format(date1, "%m") ## numeric month
[1] "03"

这些作为字符返回。如果您想将年份或数字月份作为数字变量,请在适当的情况下包含 as.numeric(),例如

> as.numeric(format(date1, "%m"))
[1] 3
> as.numeric(format(date1, "%Y"))
[1] 2012

有关详细信息,请参阅 ?yearmon?strftime - 后者解释了您可以使用的占位符。

【讨论】:

%B 表示整月,即三月“而不是”“三月” 如果有一个包含 n 个元素的 vector,我会怎么做,比如说在一个 vector 中有 1k 个日期? @Chrissl 和 R 一样,date1 也可以是日期向量。【参考方案7】:

你可以使用format:

library(zoo)
x <- as.yearmon(Sys.time())
format(x,"%b")
[1] "Mar"
format(x,"%Y")
[1] "2012"

【讨论】:

我怎样才能让月份成为一个数字? (例如 3 月?) @user1169210 我在回答中提到了这一点。例如,您希望将月份的 as.numeric(format(x, "%m")) 作为数字。

以上是关于从 zoo::yearmon 对象中提取月份和年份的主要内容,如果未能解决你的问题,请参考以下文章

如何从python中的字符串中提取月份和年份?

如何在sequelize ORM中使用从时间戳中选择并提取日期到月份和年份?

如何从熊猫数据框中提取日期/年份/月份?

如何从 MDX 查询中提取日期中的月份年份

jquery中根据年份月份获取日期

从日期时间对象中提取日期和月份