Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 257
Roland Kofler Avatar asked Mar 16 '11 21:03

Roland Kofler


People also ask

How do you convert time series to data?

Creating a time seriesThe ts() function will convert a numeric vector into an R time series object. The format is ts(vector, start=, end=, frequency=) where start and end are the times of the first and last observation and frequency is the number of observations per unit time (1=annual, 4=quartly, 12=monthly, etc.).

How do you convert time series to data in Python?

Convert data from a string to a timestamp: if we have a list of string data that resembles DateTime, we can first convert it to a dataframe using pd. DataFrame() method and convert it to DateTime column using pd. to_datetime() method.


1 Answers

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.

# 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

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

We could replace the dmn<- line with the following simpler line using @thelatemail's comment:

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

2) tapply. A more general solution using tapply is the following:

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. Then try:

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

Update

Improvement motivated by comments of @latemail below.

like image 120
G. Grothendieck Avatar answered Oct 13 '22 08:10

G. Grothendieck