Reputation: 12087
Suppose I have a univariate zoo series:
v <- read.zoo(data.frame(dt=c(as.Date('2019-01-01')+1:10), vals=1:10))
v
2019-01-02 2019-01-03 2019-01-04 2019-01-05 2019-01-06 2019-01-07 2019-01-08 2019-01-09 2019-01-10 2019-01-11
1 2 3 4 5 6 7 8 9 10
I would like to turn this into a regular zoo series with an additional column val2
which has let's say "test":
val val2
2019-01-02 1 test
2019-01-03 2 test
...
I tried the following. It logically shouldn't work (since the zoo object is univariate) but I figured since this works for a data.frame
it might work or I'd get an error or warning to guide me towards the right path which surprisingly didn't happen but it did something REALLY BAD...:
cbind(v, val2="test")
v val2
1970-01-02 <NA> test
2019-01-02 1 <NA>
2019-01-03 2 <NA>
2019-01-04 3 <NA>
2019-01-05 4 <NA>
2019-01-06 5 <NA>
2019-01-07 6 <NA>
2019-01-08 7 <NA>
2019-01-09 8 <NA>
2019-01-10 9 <NA>
2019-01-11 10 <NA>
I would have expected it to fill val2
with the value: "test" or give me some warnings/errors.
Upvotes: 0
Views: 454
Reputation: 270428
A zoo object's data is a matrix and a matrix cannot have mixed types. In partcular, it cannot have a mix of numeric and character data.
Suppose instead that the new column is val2
shown below. Then
library(zoo)
val2 <- 101:110
cbind(val = v, val2) # v is from question
giving:
val val2
2019-01-02 1 101
2019-01-03 2 102
2019-01-04 3 103
2019-01-05 4 104
2019-01-06 5 105
2019-01-07 6 106
2019-01-08 7 107
2019-01-09 8 108
2019-01-10 9 109
2019-01-11 10 110
or you can also do:
val2 <- 1
cbind(val = v, val2)
giving:
val val2
2019-01-02 1 1
2019-01-03 2 1
2019-01-04 3 1
2019-01-05 4 1
2019-01-06 5 1
2019-01-07 6 1
2019-01-08 7 1
2019-01-09 8 1
2019-01-10 9 1
2019-01-11 10 1
ADDED
Actually this does work using the development version of zoo.
# install development version of zoo
install.packages("zoo", repos="http://R-Forge.R-project.org")
res <- cbind(val = v, val2 = "test")
str(res)
giving a character matrix as the data
‘zoo’ series from 2019-01-02 to 2019-01-11
Data: chr [1:10, 1:2] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "test" "test" ...
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr [1:2] "val" "val2"
Index: Date[1:10], format: "2019-01-02" "2019-01-03" "2019-01-04" "2019-01-05" "2019-01-06" ...
which looks like this
> res
val val2
2019-01-02 1 test
2019-01-03 2 test
2019-01-04 3 test
2019-01-05 4 test
2019-01-06 5 test
2019-01-07 6 test
2019-01-08 7 test
2019-01-09 8 test
2019-01-10 9 test
2019-01-11 10 test
Upvotes: 2
Reputation: 12087
So the proper way to bind an extra column to a univariate zoo series is to bind another univariate series to it with the same index as the original series. So in my case I had to do:
cbind(v, val2 = zoo("test", index(v))
Thank you @marcus for the tip. @markus, if you would like to put a better answer feel free to post your answer and I will remove this explanation so you get full credit for your answer.
Upvotes: 0