将数据框转换为月度时间序列

10

我有一个包含100年(1200个数据点)每月数据的数据框,其中列为月份,行为年份。我想将其转换为每月时间序列,并尝试了几种方法,但没有一种能创建正确的"时间"结构。

问题在于R将数据框视为12个变量(月份)的100个观测值(年份)。以下是我最新尝试的可重现代码:

set.seed(12)
dummy.df <- as.data.frame(matrix(round(rnorm(1200),digits=2),nrow=100,ncol=12))
rownames(dummy.df) <- seq(from=1901, to=2000)
colnames(dummy.df) <- c("jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec")
dummy.df.ts <- ts(as.vector(as.matrix(dummy.df)), start=c(1901,1), end=c(2000,12), frequency=12)

在“dummy.df.ts”对象中,行和列被交换了,而且列中的观测值不是按顺序排列的,所有一月份、二月份等都被依次堆叠在一起。如何才能得到正确的时间结构?

我的数据示例:这些是从1901年到1905年的每月温度值。

fr.monthly.temp.sample  

     JAN FEB MAR  APR  MAY  JUN  JUL  AUG  SEP  OCT NOV DEC  
1901 2.7 0.4 4.7 10.0 13.0 16.9 19.2 18.3 15.7 10.6 4.9 3.5  
1902 4.1 3.2 7.5 10.3 10.0 15.1 18.2 17.4 15.0 10.2 6.3 3.5  
1903 3.8 5.9 7.6  7.1 12.9 14.9 17.6 17.3 15.5 12.1 6.9 2.7  
1904 3.0 4.6 5.5 10.3 13.6 16.3 20.2 18.5 13.9 11.2 5.4 4.8  
1905 1.7 4.0 7.4  9.3 11.9 16.5 20.0 17.6 14.7  8.4 5.5 3.8  

原始时间序列的绘图

通过使用ts()函数调用:

fr.monthly.temp.sample.ts <- ts(as.vector(as.matrix(fr.monthly.temp.sample)),                              start=c(1901,1), end=c(1905,12), frequency=12)

这是我对时间序列对象得到的输出结果:

fr.monthly.temp.sample.ts  

      Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec  
1901  2.7  4.1  3.8  3.0  1.7  0.4  3.2  5.9  4.6  4.0  4.7  7.5  
1902  7.6  5.5  7.4 10.0 10.3  7.1 10.3  9.3 13.0 10.0 12.9 13.6  
1903 11.9 16.9 15.1 14.9 16.3 16.5 19.2 18.2 17.6 20.2 20.0 18.3  
1904 17.4 17.3 18.5 17.6 15.7 15.0 15.5 13.9 14.7 10.6 10.2 12.1  
1905 11.2  8.4  4.9  6.3  6.9  5.4  5.5  3.5  3.5  2.7  4.8  3.8  

R代码中的时间序列图

--注意时间结构已更改(来自列的值现在在行中..)--

谢谢。


我已经编辑了我的回答。实际上,我并没有在plot显示的数据中经历过列和行之间的这种“切换”。也许你可以使用你的一些数据样本,只需几年的数据,并发布你得到的图表,以获得更好的答案。 - Michele
我已经添加了我的原始数据和图表以显示值的错误排序。您的EDIT 1解决方案给了我一个多元时间序列,这不是我想要的,我想将其保留为单变量系列以进行进一步处理。至于EDIT 2,我尝试了as.vector(),但这就是导致排序问题的操作。也许@Alexander发布的解决方案#1会起作用,我还需要尝试一下。 - avg
我的编辑1并不是一个解决方案... 它只是让人们了解ts()的工作原理。我的编辑2从数据已经在向量中开始... 我没有意识到你只需要转置... round(seq(5,10,length.out=24),1) 是一个向量。 - Michele
1个回答

9

方案1

您可以在向量化之前转置(使用函数t())矩阵:

set.seed(12)
dummy.df <- as.data.frame(matrix(round(rnorm(1200), digits = 2),
                                 nrow = 100, ncol = 12))
rownames(dummy.df) <- seq(1901, 2000)
colnames(dummy.df) <- month.abb
dummy.df.ts <- ts(as.vector(t(as.matrix(dummy.df))), 
                  start=c(1901,1), end=c(2000,12), frequency=12)

解决方案2

您可以通过melt数据,按日期排序,然后应用ts()函数。

以下是数据设置。 如果您的语言设置为英语,则可以使用month.abb来节省一些代码,但这对其他语言环境不稳健。

set.seed(12)
dummy.df <- as.data.frame(matrix(round(rnorm(1200),digits=2),nrow=100,ncol=12))
months <- format(seq.Date(as.Date("2013-01-01"), as.Date("2013-12-01"), 
                          by = "month"), format = "%b")
colnames(dummy.df) <- months
dummy.df$Year <- seq(1901, 2000) # set as variable, not as rownames 

将数据融合,得到一个包含1200行的数据框,每一行都代表一次观察:

library("reshape2")
dummy.df <- melt(dummy.df, id.vars = "Year")

按日期对观察结果进行排序:

dummy.df$Date <- as.Date(paste(dummy.df$Year, dummy.df$variable, "01", sep = "-"),
                         format = ("%Y-%b-%d"))
dummy.df <- dummy.df[order(dummy.df$Date), ]

然后您可以应用类似的ts()调用,使用显示所需顺序的ts对象:

dummy.df.ts <- ts(dummy.df$value, start=c(1901,1), end=c(2000,12), frequency=12)

感谢您的回答。在您发布#1之前,我尝试了#2,并得到了正确的时间序列输出。但是,我想知道如何在不使用reshape的情况下完成这个操作,因为它实际上是将值作为列向量排序,即将原始df的行从末端堆叠起来。我之前尝试过几次t()操作,但没有结果,但我认为我没有尝试过您在#1中发布的那种方法。我会告诉您结果的。 - avg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接