Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rbind support for heterogenous columns #329

Open
TravisLeithVeloqx opened this issue Mar 2, 2020 · 2 comments
Open

Add rbind support for heterogenous columns #329

TravisLeithVeloqx opened this issue Mar 2, 2020 · 2 comments
Labels
feature request New features

Comments

@TravisLeithVeloqx
Copy link

Description

I would like to be able to rbind multiple xts objects with possibly different columns.

Expected behavior

From here

All rows and all columns should be present with NA (or some other fill value) where no data was found.

As an extension (not given in Josh's SO solution), intersections should be handled with a user supplied function, like max or mean etc.

I personally think this is a natural fit for the xts package, rather than having users design their own solution similar to the link.

@joshuaulrich joshuaulrich added the feature request New features label Apr 7, 2020
@joshuaulrich
Copy link
Owner

I like this idea, though I'm not sure when I would get around to implement it.

@joshuaulrich
Copy link
Owner

Here's a reproducible example of the code in the stackoverflow Q&A the OP linked to.

# put all xts objects in a list for easier processing
x <- list(
  z1 = xts(t(c("9902"=0,"9903"=0,"9904"=0,"9905"=2,"9906"=2)),as.Date("2015-01-01")),
  z2 = xts(t(c("9902"=3,"9903"=4,"9905"=6,"9906"=5,"9908"=8)),as.Date("2015-01-02")),
  z3 = xts(t(c("9901"=1,"9903"=3,"9905"=5,"9906"=6,"9907"=7,"9909"=9)),as.Date("2015-01-03"))
)

# function to create template xts object
template <- function(xlist) {
  # find set of unique column names from all objects
  cn <- unique(unlist(lapply(xlist, colnames)))
  # create template xts object
  # using a date that doesn't occur in the actual data
  minIndex <- do.call(min, lapply(xlist, function(x) index(x[1L,])))
  # template object
  xts(matrix(0,1,length(cn)), minIndex-1, dimnames=list(NULL, sort(cn)))
}

# function to apply to each xts object
proc <- function(x, template) {
  # columns we need to add
  neededCols <- !(colnames(template) %in% colnames(x))
  # merge this object with template object, filling w/zeros
  out <- merge(x, template[,neededCols], fill=0)
  # reorder columns (NB: merge.xts always uses make.names)
  # and remove first row (from template)
  out <- out[-1L,make.names(colnames(template))]
  # set column names back to desired values
  # (using attr<- because dimnames<-.xts copies)
  attr(out, "dimnames") <- list(NULL, colnames(template))
  # return object
  out
}
(res <- do.call(rbind, lapply(x, proc, template=template(x))))
#            9901 9902 9903 9904 9905 9906 9907 9908 9909
# 2015-01-01    0    0    0    0    2    2    0    0    0
# 2015-01-02    0    3    4    0    6    5    0    8    0
# 2015-01-03    1    0    3    0    5    6    7    0    9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New features
Projects
None yet
Development

No branches or pull requests

2 participants