简体   繁体   English

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

[英]Transforming a time-series into a data frame and back

The output of a time-series looks like a data frame: 时间序列的输出看起来像一个数据帧:

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 ...

It would be handy to transform it into a data frame with columns Jan, Feb, Mar... and rows 1981, 1982, ... and then back. 将其转换为具有Jan,Feb,Mar ...列和1981、1982等行的数据框,然后再返回是很方便的。 What's the most elegant way to do this? 最优雅的方法是什么?

Here are two ways. 这有两种方法。 The first way creates dimnames for the matrix about to be created and then strings out the data into a matrix, transposes it and converts it to data frame. 第一种方法为要创建的矩阵创建暗名,然后将数据串出到矩阵中,进行转置并将其转换为数据帧。 The second way creates a by list consisting of year and month variables and uses tapply on that later converting to data frame and adding names. 第二种方法创建一个由年和月变量组成的by列表,并在之后使用tapply转换为数据框并添加名称。

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

1) matrix . 1)矩阵 This solution requires that we have whole consecutive years 此解决方案要求我们连续整整一年

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

If we don't care about the nice names it is just as.data.frame(t(matrix(tt, 12))) . 如果我们不在乎漂亮的名字,那就是as.data.frame(t(matrix(tt, 12)))

We could replace the dmn<- line with the following simpler line using @thelatemail's comment: 我们可以使用@thelatemail的注释将dmn<-行替换为以下更简单的行:

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

2) tapply . 2)轻按 A more general solution using tapply is the following: 使用tapply更一般的解决方案如下:

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

Note: To invert this suppose X is any of the solutions above. 注意:假设X是上面的任何一种解决方案,则可以将其取反。 Then try: 然后尝试:

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

Update 更新资料

Improvement motivated by comments of @latemail below. 改进来自以下@latemail的评论。

Example with the AirPassengers dataset: AirPassengers数据集的示例:

Make the data available and check its type: 使数据可用并检查其类型:

data(AirPassengers)
class(AirPassengers)

Convert Time-Series into a data frame: 将时间序列转换为数据帧:

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

Redo the creation of the Time-Series object: 重新创建时间序列对象:

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

Plot the results to ensure correct execution: 绘制结果以确保正确执行:

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

试试“ 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM