Question

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
Was it helpful?

Solution

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

OTHER TIPS

@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

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/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top