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

时间:2021-11-10 16:58:34

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. What's the most elegant way to do this?

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

1 个解决方案

#1


17  

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.

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

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

1) matrix. This solution requires that we have whole consecutive years

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

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. A more general solution using tapply is:

2)tapply。使用tapply的更通用的解决方案是:

tapply(tt, list(year = floor(time(tt)), month = month.abb[cycle(tt)]), c)

If we don't care about names we can replace month.abb[cycle(tt)] with just cycle(tt).

如果我们不关心名称,我们可以用cycle(tt)替换month.abb [cycle(tt)]。

Note: To invert this suppose DF is any of the data frame solutions above. Then try:

注意:要反转这一点,假设DF是上面的任何数据帧解决方案。然后尝试:

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

#1


17  

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.

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

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

1) matrix. This solution requires that we have whole consecutive years

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

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. A more general solution using tapply is:

2)tapply。使用tapply的更通用的解决方案是:

tapply(tt, list(year = floor(time(tt)), month = month.abb[cycle(tt)]), c)

If we don't care about names we can replace month.abb[cycle(tt)] with just cycle(tt).

如果我们不关心名称,我们可以用cycle(tt)替换month.abb [cycle(tt)]。

Note: To invert this suppose DF is any of the data frame solutions above. Then try:

注意:要反转这一点,假设DF是上面的任何数据帧解决方案。然后尝试:

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