将日期更改为R中的yyyy-mm



我有一个将用于时间序列的数据集。当前日期列的结构如下:

> head(cam_shiller)
div stock  dates
1 0.495  7.09 1933m1
2 0.490  6.25 1933m2
3 0.485  6.23 1933m3
4 0.480  6.89 1933m4
5 0.475  8.87 1933m5
6 0.470 10.39 1933m6

如果我没有记错的话,时间序列的月度数据应该是这样的:yyyy-mm。所以我试着让我的约会专栏看起来像这样:

div stock  dates
1 0.495  7.09 1933-01
2 0.490  6.25 1933-02
3 0.485  6.23 1933-03
4 0.480  6.89 1933-04
5 0.475  8.87 1933-05
6 0.470 10.39 1933-06

但是,使用as.yearmo函数会生成一列充满NA的列。我尝试删除"m"并将其替换为破折号,然后再次运行as.yearmo。现在的结果是这样的:

div stock    dates
1 0.495  7.09 Jan 1933
2 0.490  6.25 Feb 1933
3 0.485  6.23 Mar 1933
4 0.480  6.89 Apr 1933
5 0.475  8.87 May 1933
6 0.470 10.39 Jun 1933

如何将日期更改为yyyy-mm格式?

library(zoo)
cam_shiller = read.csv('https://raw.githubusercontent.com/bandcar/Examples/main/cam_shiller.csv')
cam_shiller$dates = gsub('m', '-', cam_shiller$dates)
cam_shiller$dates = as.yearmon(cam_shiller$dates)

实际上,在ts中,您只需要指定start=frequency

res <- ts(cam_shiller[, -3], start=1933, frequency=12)
res
#             div stock
# Jan 1933 0.4950  7.09
# Feb 1933 0.4900  6.25
# Mar 1933 0.4850  6.23
# Apr 1933 0.4800  6.89
# May 1933 0.4750  8.87
# Jun 1933 0.4700 10.39
# Jul 1933 0.4650 11.23
# Aug 1933 0.4600 10.67
# Sep 1933 0.4550 10.58
# Oct 1933 0.4500  9.55
# Nov 1933 0.4450  9.78
# Dec 1933 0.4400  9.97
# Jan 1934 0.4408 10.54
# Feb 1934 0.4417 11.32
# Mar 1934 0.4425 10.74
# Apr 1934 0.4433 10.92
# May 1934 0.4442  9.81
# Jun 1934 0.4450  9.94
# Jul 1934 0.4458  9.47
# Aug 1934 0.4467  9.10
# Sep 1934 0.4475  8.88
# Oct 1934 0.4483  8.95
# Nov 1934 0.4492  9.20
# Dec 1934 0.4500  9.26
# ...

ts(cam_shiller$stock, start=c(1933, 1), frequency=12)
#  Jan    Feb    Mar    Apr    May    Jun    Jul    Aug    Sep    Oct    Nov    Dec
# 1933   7.09   6.25   6.23   6.89   8.87  10.39  11.23  10.67  10.58   9.55   9.78   9.97
# 1934  10.54  11.32  10.74  10.92   9.81   9.94   9.47   9.10   8.88   8.95   9.20   9.26
# 1935   9.26   8.98   8.41   9.04   9.75  10.12  10.65  11.37  11.61  11.92  13.04  13.04
# ...

明智的做法是,通过评估年份和月份矩阵的列和行方差,事先检查数据中是否存在缺口:

test <- do.call(rbind, strsplit(cam_shiller$dates, 'm')) |>
type.convert(as.is=TRUE) 
matrixStats::colVars(matrix(test[, 1], 12))
#  [1] 0 0 ...
matrixStats::rowVars(matrix(test[, 2], 12))
# [1] 0 0 0 0 0 0 0 0 0 0 0 0

如果您使用xts::xts,它是相当挑剔的,因为它想要一个基于时间的类,如"Date""POSIXct"。因此,您需要完整的日期,即paste01作为伪日期。

res <- transform(cam_shiller, dates=strptime(paste(dates, '01'), format='%Ym%m %d')) |>
{(.) xts::as.xts(.[1:2], .$dates)}()
head(res)
#              div stock
# 1933-01-01 0.495  7.09
# 1933-02-01 0.490  6.25
# 1933-03-01 0.485  6.23
# 1933-04-01 0.480  6.89
# 1933-05-01 0.475  8.87
# 1933-06-01 0.470 10.39
class(res)
# [1] "xts" "zoo"

数据:

cam_shiller <- structure(list(div = c(0.495, 0.49, 0.485, 0.48, 0.475, 0.47, 
0.465, 0.46, 0.455, 0.45, 0.445, 0.44, 0.4408, 0.4417, 0.4425, 
0.4433, 0.4442, 0.445, 0.4458, 0.4467, 0.4475, 0.4483, 0.4492, 
0.45), stock = c(7.09, 6.25, 6.23, 6.89, 8.87, 10.39, 11.23, 
10.67, 10.58, 9.55, 9.78, 9.97, 10.54, 11.32, 10.74, 10.92, 9.81, 
9.94, 9.47, 9.1, 8.88, 8.95, 9.2, 9.26), dates = c("1933m1", 
"1933m2", "1933m3", "1933m4", "1933m5", "1933m6", "1933m7", "1933m8", 
"1933m9", "1933m10", "1933m11", "1933m12", "1934m1", "1934m2", 
"1934m3", "1934m4", "1934m5", "1934m6", "1934m7", "1934m8", "1934m9", 
"1934m10", "1934m11", "1934m12")), row.names = c(NA, 24L), class = "data.frame")

尝试lubridate::ym将日期更改为yyyy-mm格式的

library(tidyverse)
cam_shiller = read.csv('https://raw.githubusercontent.com/bandcar/Examples/main/cam_shiller.csv')
cam_shiller %>% 
mutate(
date = lubridate::ym(dates),
date = strftime(date, "%Y-%m")
) %>% 
head()
#>     div stock  dates    date
#> 1 0.495  7.09 1933m1 1933-01
#> 2 0.490  6.25 1933m2 1933-02
#> 3 0.485  6.23 1933m3 1933-03
#> 4 0.480  6.89 1933m4 1933-04
#> 5 0.475  8.87 1933m5 1933-05
#> 6 0.470 10.39 1933m6 1933-06

创建于2022-10-01,reprex v2.0.2

问题中的形式已经正确。这不是真的您需要更改它。它呈现为1933年1月等,但在内部它表示为年+(月-1(/12(其中月是数字1、2、…、12(,这正是您进行分析所需要的。您不希望使用yyyy-mm格式的字符串进行分析。

如果通过";时间序列";你指的是一个动物园系列,然后使用结尾注释中定义的u,下面的z给出了一个年鉴索引。read.csv.zooindex参数给出索引的列号或名称,FUN参数告诉如何转换,format参数告诉日期的精确形式。

如果你所说的时间序列是指你想要一个ts序列,那么下面的tt给出了这个。

如果你的意思是一个有年份栏的数据框架,那么下面的DF给出了这个结果。

无论是动物园系列还是ts系列,都可以进行各种分析。例如,acf(z)acf(tt)将给出自相关函数。

有关详细信息,请参阅?read.csv.zoo。read.zoo及其变体上也有一个完整的小插曲。这些小插曲链接到动物园的CRAN主页上。另请参阅?strptime了解百分比代码。

library(zoo)
# zoo series with yearmon column
z <- read.csv.zoo(u, index = 3, FUN = as.yearmon, format = "%Ym%m")
# ts series
tt <- as.ts(z)
# data frame with yearmon column
DF <- u |>
read.csv() |>
transform(dates = as.yearmon(dates, "%Ym%m"))

yyyy-mm形式的字符串不适合大多数分析,但如果你真的想要,那么

# zoo series with yyyy-mm character string index
z2 <- aggregate(z, format(index(z), "%Y-%m"), c)
# data.frame with yyyy-mm character string column
DF2 <- transform(DF, dates = format(dates, "%Y-%m"))

备注

u <- "https://raw.githubusercontent.com/bandcar/Examples/main/cam_shiller.csv"

相关内容

  • 没有找到相关文章

最新更新