【发布时间】:2023-04-05 09:12:01
【问题描述】:
我有一个yearmon 对象:
require(zoo)
date1 <- as.yearmon("Mar 2012", "%b %Y")
class(date1)
# [1] "yearmon"
如何从中提取月份和年份?
month1 <- fn(date1)
year1 <- fn(date1)
我应该用什么函数代替fn()
【问题讨论】:
我有一个yearmon 对象:
require(zoo)
date1 <- as.yearmon("Mar 2012", "%b %Y")
class(date1)
# [1] "yearmon"
如何从中提取月份和年份?
month1 <- fn(date1)
year1 <- fn(date1)
我应该用什么函数代替fn()
【问题讨论】:
基于 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
【讨论】:
从 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
【讨论】:
对于大向量:
y = as.POSIXlt(date1)$year + 1900 # x$year : years since 1900
m = as.POSIXlt(date1)$mon + 1 # x$mon : 0–11
【讨论】:
POSIXlt 对象,这使得 zoo 包变得不必要
我知道 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"))
【讨论】:
lubridate package 非常适合这种事情:
> require(lubridate)
> month(date1)
[1] 3
> year(date1)
[1] 2012
【讨论】:
lubridate 包并尝试安装它并使用 year(date) 但它给出的是日期而不是年份仅适用于格式为“2015-05-06”的日期?
对"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 - 后者解释了您可以使用的占位符。
【讨论】:
vector,我会怎么做,比如说在一个 vector 中有 1k 个日期?
date1 也可以是日期向量。
你可以使用format:
library(zoo)
x <- as.yearmon(Sys.time())
format(x,"%b")
[1] "Mar"
format(x,"%Y")
[1] "2012"
【讨论】:
as.numeric(format(x, "%m")) 作为数字。