5

I am using the eventstudies package. I am using the phys2eventtime(..) to set up my data. However I am getting

Error in `colnames<-`(`*tmp*`, value = integer(0)) : 
  attempt to set 'colnames' on an object with less than two dimensions

My guess is that, my data is wrongly formated. When I have a look at the example data which use the function in the sample:

    > es <- phys2eventtime(z=StockPriceReturns, events=SplitDates, width=10)
    > (str(StockPriceReturns))
'zoo' series from 2000-04-03 to 2013-03-28
  Data: num [1:3246, 1:30] NA NA NA NA NA NA NA NA NA NA ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:30] "Bajaj.Auto" "BHEL" "Bharti.Airtel" "Cipla" ...
  Index:  Date[1:3246], format: "2000-04-03" "2000-04-04" "2000-04-05" "2000-04-06" ...
NULL

compared to this my data looks like that:

> (str(zoo_Data))
'zoo' series from 2002-01-01 to 2013-08-20
  Data: num [1:3036] 183 183 186 191 191 ...
  Index:  Date[1:3036], format: "2002-01-01" "2002-01-02" "2002-01-03" "2002-01-04" ...
NULL    

This is different:

  • The sample data uses sth like - attr(*, "dimnames")=List of 2

This can also be seen when looking at the raw data:

sample data:

> (head(StockPriceReturns))
           Bajaj.Auto       BHEL Bharti.Airtel     Cipla Coal.India   Dr.Reddy
2000-04-03         NA  4.9171044            NA  6.810041         NA -3.2541653
2000-04-04         NA -8.3348496            NA -3.368606         NA -8.3353739
2000-04-05         NA  0.3305788            NA  0.836825         NA  0.2616345
2000-04-06         NA -2.7605266            NA -2.466056         NA -1.8941289
2000-04-07         NA  3.2543548            NA  7.690426         NA  7.6961041
2000-04-10         NA  3.3107586            NA  6.154276         NA  6.4769648

my data:

> (head(zoo_Data))
2002-01-01 2002-01-02 2002-01-03 2002-01-04 2002-01-07 2002-01-08 
    182.83     182.83     186.40     190.57     191.17     193.25 

The df data:

I am constructing the zoo object out of my data like that:

> dfToZoo <- function(df) {
    require(zoo)
    date <- as.Date(df[, 1], format = '%d.%m.%Y')
    #TODO have a look if the column are rightly named
    with(df, zoo(TotalReturns, date))
} 


csv_data <- read.csv(..., header = TRUE, sep = ";",stringsAsFactors=FALSE)

totalReturns <- (as.double(gsub(",",".",csv_data$TotalReturn)))


df <- data.frame(csv_data$Date, totalReturns)
names(df) <- c("Date" ,"TotalReturns")


zoo_Data <- dfToZoo(df)

How to add the attr(*, "dimnames")=List of 2 to my data?

I appreciate your replies!

UPDATE 1

This is the example data code from the libary package:

library(eventstudies)
library(zoo)

###########################

# Load data

(data(SplitDates))
(data(StockPriceReturns))

data <- StockPriceReturns

(head(StockPriceReturns))



es <- phys2eventtime(z=StockPriceReturns, events=SplitDates, width=10)
es.w <- window(es$z.e, start=-10, end=10)
SplitDates[1:3,]

UPDATE 2

This is how my own data is formatted:

> (str(s_dates))
'data.frame':   36799 obs. of  2 variables:
 $ unit: chr  "ZAE000006284" "ZAE000006284" "ZAE000006284" "ZAE000006284" ...
 $ when: Date, format: "2003-12-18" "2005-04-06" ...
NULL
> (str(zoo_Data))
'zoo' series from 2002-01-01 to 2013-08-20
  Data: num [1:3036] 183 183 186 191 191 ...
  Index:  Date[1:3036], format: "2002-01-01" "2002-01-02" "2002-01-03" "2002-01-04" ...
NULL

This is how the data from the event study package is formatted:

> (str(SplitDates))
'data.frame':   22 obs. of  2 variables:
 $ unit: chr  "BHEL" "Bharti.Airtel" "Cipla" "Coal.India" ...
 $ when: Date, format: "2011-10-03" "2009-07-24" ...
NULL
> (str(StockPriceReturns))
'zoo' series from 2000-04-03 to 2013-03-28
  Data: num [1:3246, 1:30] NA NA NA NA NA NA NA NA NA NA ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:30] "Bajaj.Auto" "BHEL" "Bharti.Airtel" "Cipla" ...
  Index:  Date[1:3246], format: "2000-04-03" "2000-04-04" "2000-04-05" "2000-04-06" ...
NULL

UPDATE 3

Reproducable example

I am initially reading the data in by different csv files. Please see my reproducable example:

Reproducable example

library(eventstudies)
library(zoo)

s_dates <- 
  structure(list(unit = c("ZAE000006284", "ZAE000006284", "ZAE000006284", 
                          "ZAE000006284", "ZAE000006284", "XS0430907989", "XS0430907989"
  ), when = structure(c(12404, 12879, 12879, 12880, 12930, 14411, 
                        14411), class = "Date")), .Names = c("unit", "when"), row.names = c(NA, 
                                                                                            7L), class = "data.frame")

zoo_Data <- 
  structure(c(182.83, 182.83, 186.4, 190.57, 191.17, 193.25, 190.57
  ), index = structure(c(11688, 11689, 11690, 11691, 11694, 11695, 
                         11696), class = "Date"), class = "zoo")

es <- phys2eventtime(z=zoo_Data, events=s_dates, width=10)
Error in `colnames<-`(`*tmp*`, value = integer(0)) : 
  attempt to set 'colnames' on an object with less than two dimensions
> es.w <- window(es$z.e, start=-10, end=10)
  Error in window(es$z.e, start = -10, end = 10) : object 'es' not found

UPDATE 4

Ok when I try to convert my zoo_data:

> library(eventstudies)
> library(zoo)
> 
> s_dates <- dput(head(s_dates,30))
structure(list(unit = c("ZAE000006284", "ZAE000006284", "ZAE000006284", 
"ZAE000006284", "ZAE000006284", "XS0430907989", "XS0430907989", 
"XS0302626899", "XS0302626899", "XS0302626899", "XS0302626899", 
"XS0302626899", "XS0302626899", "XS0266838746", "XS0187043079", 
"XS0187043079", "XS0187043079", "XF0000TZ7757", "XF0000AK5197", 
"XF0000AK5197", "XF0000AK5197", "XF0000AK5197", "XF0000AK5197", 
"USU02681027", "USU026281027", "USU026281027", "USU026281027", 
"USU026281027", "USU026281027", "USU026281027"), when = structure(c(12404, 
12879, 12879, 12880, 12930, 14411, 14411, 14599, 14600, 15134, 
15139, 15328, 15328, 13913, 14330, 14335, 14593, 13049, 12953, 
12954, 12954, 12954, 12955, 12934, 13537, 13537, 13537, 13648, 
13649, 13649), class = "Date")), .Names = c("unit", "when"), row.names = c(NA, 
30L), class = "data.frame")
> zoo_Data <- dput(head(zoo_Data,30))
structure(c(182.83, 182.83, 186.4, 190.57, 191.17, 193.25, 190.57, 
184.02, 181.34, 172.11, 169.73, 160.2, 175.09, 172.11, 170.92, 
176.58, 171.51, 170.92, 173.9, 168.54, 167.34, 166.75, 166.45, 
167.34, 164.37, 159.01, 158.11, 154.84, 156.63, 161.99), index = structure(c(11688, 
11689, 11690, 11691, 11694, 11695, 11696, 11697, 11698, 11701, 
11702, 11703, 11704, 11705, 11708, 11709, 11710, 11711, 11712, 
11715, 11716, 11717, 11718, 11719, 11722, 11723, 11724, 11725, 
11726, 11729), class = "Date"), class = "zoo")
> 
> n = 20                       ## number of observation
> cn <- unique(s_dates$unit)   ## get response variable 
> 
> as.xts(zoo_Data)
> 
> names(zoo_Data) <- cn
> 
> es <- phys2eventtime(z=zoo_Data), events=s_dates, width=10)
Error in `colnames<-`(`*tmp*`, value = integer(0)) : 
  attempt to set 'colnames' on an object with less than two dimensions
> es.w <- window(es$z.e, start=-3, end=3)
Error in window(es$z.e, start = -3, end = 3) : object 'es' not found
user2051347
  • 1,609
  • 4
  • 23
  • 34
  • 1
    I am using the same lib at the moment and facing the same problem. Would love to hear some answers! – Carol.Kar Jan 04 '14 at 09:50
  • 1
    I can't reproduce the problem. In your first example there isn't splitDates and the second update it works fine. – agstudy Jan 04 '14 at 10:57
  • @agstudy I added `Update 2` to to make my problem much more clearer. Please ask if anything further is unclear! – user2051347 Jan 04 '14 at 11:50
  • Thank's but I am afraid to say that your example still not reproducible. Please read [this](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – agstudy Jan 04 '14 at 12:11
  • 1
    @agstudy Thanks a lot for this tip. I think I created now a `Reproducable Example`. – user2051347 Jan 04 '14 at 12:42

3 Answers3

5

phys2eventtime Converts physical dates to event dates.

So Given a zoo time-series and an event date, it converts the physical date to the event date. That means , if it finds an event date in the range of the zoo object , this date becomes zero and all other dates shift accordingly.

So giving this event date object:

          unit       when
1 ZAE000006284 2003-12-18
2 ZAE000006284 2005-04-06
3 ZAE000006284 2005-04-06
4 ZAE000006284 2005-04-07
5 ZAE000006284 2005-05-27
6 XS0430907989 2009-06-16
7 XS0430907989 2009-06-16

Conditions to convert ts --> event date

You physical time series dates (the zoo object) should fulfill 2 conditions:

  • should have at least one column name (response variable) within unit values (COND1)
  • the range date of this response variable should contain at least one event date ( when column).(COND2)

Create a physical time series that can be converted to an event date

Now I will create a times serie that fulfill this 2 conditions : a multi time series (xts object ) which index fall with the range of s_dates and having column names within s_dates unit values.

n = 20                       ## number of observation
cn <- unique(s_dates$unit)   ## get response variable 
rr = range(s_dates$when)     ## get date range
## COND2
index = seq(rr[1],rr[2],length.out=n)   
mat = matrix(round(runif(n*2,min=150,max=200),2),ncol=2)
ev.dat = xts(mat,index)
## COND1
names(ev.dat) <- cn

Checking our time serie object:

head(ev.dat)
           ZAE000006284 XS0430907989
2003-12-18       183.27       152.89
2004-04-01       195.23       172.78
2004-07-16       190.18       164.92
2004-10-29       182.24       191.19
2005-02-12       151.78       195.81
2005-05-29       153.78       189.27

And without surprise it works fine :

(es <- phys2eventtime(z=ev.dat, events=s_dates, width=5))
(es.w <- window(es$z.e, start=-10, end=10))
head(es.w)
        2      3      4      5
-4 197.28 197.28 197.28 197.28
-3 158.54 158.54 158.54 158.54
-2 180.56 180.56 180.56 180.56
-1 194.41 194.41 194.41 194.41
0  157.64 157.64 157.64 157.64
1  151.06 151.06 151.06 151.06

How to test if your time series fulfill this 2 conditions:

As a bonus , I created a small function that 2 conditions for you:

check.phys2ev <- function(ev.dat,s_dates){
  is.sucess = lapply(s_dates$when,function(when){
    inter = findInterval(when, index(ev.dat))
    inter < nrow(ev.dat) && inter >1 
  })
  sum(unlist(is.sucess)) >0 &
    all(colnames(ev.dat) %in% s_dates$unit)
}

check.phys2ev(ev.dat,s_dates)
[1] TRUE
agstudy
  • 119,832
  • 17
  • 199
  • 261
  • Wow thx for your answer! When you convert to an xts object: Why are you using only `r[1],r[2]`? Why are you constructin a matrix `mat`? – user2051347 Jan 04 '14 at 20:18
  • do you mean rr[1],rr[2]? because `range` creates length 2, rr[1) is min dates and rr[2] is max dates. I create a matrix because in xts constructor , xts(x,index): x is a matrix and index a vector of dates. – agstudy Jan 04 '14 at 20:34
  • Thx for your answer! Can I also create the `ev.dat` object out of my already existing zoo object which are in fact my data for the `StockPriceReturns`? Namely in fact my s_date consists of in my full dataset of `36799` values and my zoo_object consists of `3036`. – user2051347 Jan 04 '14 at 20:41
  • Yes I tried it. However I still get the same error. Please see my further `update`. – user2051347 Jan 04 '14 at 21:06
  • 1
    @user2051347 please read my answer carefully! `ev.dat <- as.xts(zoo_Data)` then you shouldname it with one of the variable `names(ev.dat) <- cn[1]` or 2... then use my test function to check the range of dates! – agstudy Jan 04 '14 at 21:13
  • Thank you for your answer and all your help! I have one final question. After coding my program out I found out that it is now applicable to just use a univariat data set, cause I would process each dataset by dataset, which would take me days(by an estimate of 36000 events and around 1000 companies). So I was wondering I could just add to my xts object other zoo objects, so that the datastructure looks exactly like the `StockPriceReturns`. I would really appreciate your answer! – user2051347 Jan 05 '14 at 17:52
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44570/discussion-between-agstudy-and-user2051347) – agstudy Jan 05 '14 at 19:44
2

@agstudy has already presented a very nice answer, using a multi variate time series as an example. Because you seem to have a univariate time series, I wish to add something on how to avoid coercion to an "object with less than two dimensions" when you create your zoo object. Here is one possible solution, where I add a dummy column to the time series, and select the focal column while using drop = FALSE.

Start with a univariate time series in a data frame. This first attempt clearly doesn't work due to the mismatch between dates in the zoo object and in events (as described by @agstudy), as well as the fact that the zoo object has less than two dimensions.

df <- data.frame(date = index(zoo_Data),
                 ZAE000006284 = coredata(zoo_Data))
df

# convert to zoo object
z1 <- zoo(x = df[ , -1], order.by = df$date)
z1

phys2eventtime(z = z, events = s_dates, width = 10)
# Error in `colnames<-`(`*tmp*`, value = integer(0)) : 
#   attempt to set 'colnames' on an object with less than two dimensions

Add a date that is as large as max date in s_dates, just used here as a quick and dirty way to fulfil "COND2" (sensu @agstudy).

df <- data.frame(date = c(index(zoo_Data), max(s_dates$when)),
                 ZAE000006284 = c(coredata(zoo_Data), 200))
df

z1 <- zoo(x = df[ , -1], order.by = df$date)
z1
phys2eventtime(z = z1, events = s_dates, width = 10)
# Error in `colnames<-`(`*tmp*`, value = integer(0)) : 
#   attempt to set 'colnames' on an object with less than two dimensions

Avoid coercion to vector
Add a dummy column to the univariate time series. When the focal column is selected, use drop = FALSE to avoid coercion to vector. Then convert the univariate (but two-dimensional) time series to zoo:

df <- data.frame(date = c(index(zoo_Data), max(s_dates$when)),
                 ZAE000006284 = c(coredata(zoo_Data), 200),
                 ZAE000006284_2 = c(coredata(zoo_Data), 200))
df

z2 <- zoo(x = df[ , "ZAE000006284", drop = FALSE], order.by = df$date)
z2
str(z2)   
....
attr(*, "dimnames")=List of 2


phys2eventtime(z = z2, events = s_dates, width = 10)
# seems to work
Henrik
  • 65,555
  • 14
  • 143
  • 159
  • +1! I think that this should be added to the function ( `drop=FALSE`) .Maybe you or the OP you can contact the package maintainer. – agstudy Jan 04 '14 at 19:13
  • 2
    @agstudy, Thanks for your feedback. I can notify the package maintainer about this question. – Henrik Jan 04 '14 at 19:26
1

Thanks everyone for pointing this out and the great discussion. Being one of the authors of the package, I see where the problem is. If you look at the phys2eventtime function, it requires a zoo series with at least one column, as pointed out in the answers above. zoo/data.frame drops the last column and converts it to a vector unless drop = FALSE is provided to the subscript function.

As suggested by @Henrik and @agstudy, we cannot really do drop = FALSE inside the phys2eventtime function since the function does not know the series name. It relies on colnames of the object for the series names. For univariate series, if the object is a vector, then there is no way to know the series name and match it with the events object.

The only way I see now is by creating one-column zoo objects. Suggestions are of course welcome.

EDIT: I am submitting a small patch which throws out an error if the 'z' object is a vector:

if (is.null(ncol(z))) { stop(paste(deparse("z"), "should be a zoo series with at least one column.")) }

The code is available here: https://r-forge.r-project.org/scm/viewvc.php/?root=eventstudies

Kindly also join the package discussion mailing list at: http://lists.r-forge.r-project.org/pipermail/eventstudies-discussion/

Henrik
  • 65,555
  • 14
  • 143
  • 159