将时间序列转换为数据帧并返回

时间:2011-03-16 21:18:46

标签: r dataframe time-series

时间序列的输出看起来像数据框:

ts(rnorm(12*5, 17, 8), start=c(1981,1), frequency = 12)

       Jan       Feb       Mar       Apr       May       Jun       Jul     ...
1981 14.064085 21.664250 14.800249 -5.773095 16.477470  1.129674 16.747669 ...
1982 23.973620 17.851890 21.387944 28.451552 24.177141 25.212271 19.123179 ...
1983 19.801210 11.523906  8.103132  9.382778  4.614325 21.751529  9.540851 ...
1984 15.394517 21.021790 23.115453 12.685093 -2.209352 28.318686 10.159940 ...
1985 20.708447 13.095117 32.815273  9.393895 19.551045 24.847337 18.703991 ...

将它转换为包含Jan,Feb,Mar ......和1981,1982行......的数据框将会很方便。最优雅的方法是什么?

3 个答案:

答案 0 :(得分:21)

这有两种方法。第一种方法为即将创建的矩阵创建dimnames,然后将数据串行化为矩阵,转置它并将其转换为数据帧。第二种方法创建一个由年份和月份变量组成的by列表,并使用tapply,稍后转换为数据框并添加名称。

# create test data
set.seed(123)
tt <- ts(rnorm(12*5, 17, 8), start=c(1981,1), frequency = 12)

1)矩阵。这个解决方案要求我们连续几年

dmn <- list(month.abb, unique(floor(time(tt))))
as.data.frame(t(matrix(tt, 12, dimnames = dmn)))

如果我们不关心好名字,那只是as.data.frame(t(matrix(tt, 12)))

我们可以使用@thelatemail的评论用以下更简单的行替换dmn<-行:

dmn <- dimnames(.preformat.ts(tt))

2)tapply 。使用tapply的更一般的解决方案如下:

Month <-  factor(cycle(tt), levels = 1:12, labels = month.abb)
tapply(tt, list(year = floor(time(tt)), month = Month), c)

注意:要反转此假设X是上述任何解决方案。然后尝试:

ts(c(t(X)), start = 1981, freq = 12)

更新

以下@latemail的评论推动了改进。

答案 1 :(得分:1)

AirPassengers数据集的示例:

使数据可用并检查其类型:

data(AirPassengers)
class(AirPassengers)

将时间序列转换为数据帧:

df <- data.frame(AirPassengers, year = trunc(time(AirPassengers)), 
month = month.abb[cycle(AirPassengers)])

重新创建时间序列对象:

tsData = ts(df$AirPassengers, start = c(1949,1), end = c(1960,12), frequency = 12)

绘制结果以确保正确执行:

components.ts = decompose(tsData)
plot(components.ts)

答案 2 :(得分:0)

尝试打包“ tsbox”

ts = ts(rnorm(12*5, 17, 8), start=c(1981,1), frequency = 12) df = ts_df(ts) str(df)

data.frame: 60 obs. of 2 variables: time : Date, format: "1981-01-01" "1981-02-01" value: num 23.15 22.77 5.1 1.05 13.87