bttomio
bttomio

Reputation: 2306

Merging two lists of time-series objects (ts) into a new a list

I have several lists of time-series for several countries. Is it possible to merge them while keeping a list for each country (listing all variables)?

As an example, please consider this data for one country (CHE):

GDP <- list(CHE = structure(c(99.8434859769227, 99.5344620742553, 97.238582764046, 
95.0831648559733, 93.0539540272435), index = c("2020-01", "2020-02", 
"2020-03", "2020-04", "2020-05"), class = "ts", .Tsp = c(2020, 
2020.33333333333, 12)))

EXPRT <- list(CHE = structure(c(21.4220407907972, 20.8542317603181, 20.9518846384104, 
17.261560042682, 16.5993061452528), index = c("2020-01", "2020-02", 
"2020-03", "2020-04", "2020-05"), class = "ts", .Tsp = c(2020, 
2020.33333333333, 12)))

This is what I have tried so far, resulting in a complete merge:

list12 <- Map(c, GDP, EXPRT) 

Desired output would be a list with the country CHE list for both variables.

Upvotes: 0

Views: 323

Answers (2)

akrun
akrun

Reputation: 887811

May be we can merge after converting to zoo

library(zoo) 
Map(function(x, y) merge(GDP = as.zoo(x), EXPRT = as.zoo(y)), GDP, EXPRT)

-output

#$CHE
#              GDP    EXPRT
#Jan 2020 99.84349 21.42204
#Feb 2020 99.53446 20.85423
#Mar 2020 97.23858 20.95188
#Apr 2020 95.08316 17.26156
#May 2020 93.05395 16.59931

Or with xts

library(xts)
lst1 <- Filter(function(x) inherits(x, "list") && 
         all(sapply(x, inherits, "ts")), mget(ls()))
out <- lapply(do.call(Map, c(f = function(...) Reduce(merge, 
     lapply(list(...), as.xts)), lst1)), function(x) {
          colnames(x) <- names(lst1)
     x})
out1 <- lapply(out, ts, start = c(2020, 1), frequency = 12)

Upvotes: 1

G. Grothendieck
G. Grothendieck

Reputation: 270160

I am not clear on precisely what the output should be but if we create a vector of names and use mget to get a named list of the contents then combining them as shown will give a list L and then using cbind on that to give a single mts/ts object. This also works if nms has more than 2 elements.

If you want a list omit the the last line -- the names will be the same as shown below -- or if you want a single mts/ts object use the entire code.

nms <- c("GDP", "EXPRT")
L <- do.call("c", mget(nms))
do.call("cbind", L)
##           GDP.CHE EXPRT.CHE
## Jan 2020 99.84349  21.42204
## Feb 2020 99.53446  20.85423
## Mar 2020 97.23858  20.95188
## Apr 2020 95.08316  17.26156
## May 2020 93.05395  16.59931

Upvotes: 1

Related Questions