mpiktas
mpiktas

Reputation: 11518

Why cbind for ts objects behaves different from cbind for matrices and data.frames in R?

Does anyone why the result of the following code is different?

a <- cbind(1:10,1:10)
b <- a
colnames(a) <- c("a","b")
colnames(b) <- c("c","d")

colnames(cbind(a,b))
> [1] "a" "b" "c" "d"
colnames(cbind(ts(a),ts(b)))
> [1] "ts(a).a" "ts(a).b" "ts(b).c" "ts(b).d"

Is this or compatibility reasons? Cbind for xts and zoo does not have this feature.

I always accepted this as given, but now my code is littered with the following:

ca<-colnames(a)
cb<-colnames(b)
out <- cbind(a,b)
colnames(out) <- c(ca,cb)

Upvotes: 3

Views: 655

Answers (2)

dynamo
dynamo

Reputation: 3028

I take it that you're interested in why this happens.

Taking a look at the body of stats:::.cbind.ts, which is the function that does column binding for time series, shows that naming is performed by .makeNamesTs. Taking a look at stats:::.make.Names.Ts reveals that the names are derived directly from the arguments you pass to cbind, and there is no obvious way to influence this. As an example, try:

cbind(ts(a),ts(b, start = 2))

You will find that the start specification of the second time series appears in the name of the respective columns.

As to why that's the way things are ... I can't help you there!

Upvotes: 0

Joshua Ulrich
Joshua Ulrich

Reputation: 176648

This is just what the cbind.ts method does. You can see the relevant code via stats:::cbind.ts, stats:::.cbind.ts, and stats:::.makeNamesTs.

I can't explain why it was made to be different, since I didn't write it, but here's a work-around.

cbts <- function(...) {
  dots <- list(...)
  ists <- sapply(dots,is.ts)
  if(!all(ists)) stop("argument ", which(!ists), " is not a ts object")
  do.call(cbind,unlist(lapply(dots,as.list),recursive=FALSE))
}

Upvotes: 2

Related Questions