Pregunta

The function my.ccf generates a plot among other things.

my.ccf <- function(dat)
{
require(forecast)
modx <- auto.arima(dat[,1])
modx$series <- colnames(dat)[1]
mody <- Arima(dat[,2], model=modx)
mody$series <- colnames(dat)[2]
ccf1 <- ccf(residuals(modx), residuals(mody), type="correlation", ylab="CCF", 
            main=paste(colnames(dat)[1], "&", colnames(dat)[2], sep=" "))
return(list(modx=modx, mody=mody, ccf=ccf1))    
}
dat1 <- data.frame(p=rnorm(50), q=rnorm(50)); my.ccf(dat1) 

The figure produced has 'p & x' etc as title

I’m applying this function on another data.frame (dat2) using do.call inside the function year.ccf. First it'll subset the passed data.frame by year (I have separate function to do that. For illustrative purpose I use for loop here) and then apply my.ccf on the paired combination of column named 'x' with the columns given in var.do. Length of var.do varies form 3 to 9. I have to do it repeatedly many times (more than 500 times) on different data frame and trying to do as automatic as possible.

year.ccf1 <- function(dat, var.do=c('a','b'))
{
year.form <- format(dat2$date, '%Y')
dat$year <- factor(year.form, levels=unique(year.form), ordered=TRUE)
yl <- levels(dat$year)
ydat <- list()
for(i in 1:length(yl))
ydat[[i]] <- subset(dat,year==yl[i])
wdat <- list()
for(i in 1:length(yl)){  
a <- list()
for(j in 1:length(var.do)){
#par(mfrow=c(2,2))
a[[j]] <- do.call(my.ccf, list(ydat[[i]][,eval(c(var.do[j],'x'))]))
}
names(a) <- var.do
wdat[[i]] <- a         
}
names(wdat) <- yl
return(wdat)
}
date <- seq(as.Date("2011/1/1"), as.Date("2013/8/1"),  by = "months")
dat2 <- data.frame(date=date,x =rnorm(length(date)), y=rnorm(length(date)),        
a=rnorm(length(date)),b=rnorm(length(date)))
pdf("./temp/dat2.pdf")
A <- year.ccf1(dat2, var.do=c('a', 'b'))
dev.off()

I'm trying to change the title of each plot in dat2.pdf to have Year stamp with the column name, such as "Year 2011: CCF of a & x'. Not sure whether I'm missing something obvious or don't understand how to put to argument in one do.call like below.

do.call(my.ccf, main=paste("Year ", yl[i], var.do[j], " & x", sep=" "), list(ydat[[i]
[,eval(c(var.do[j],'x'))]))

Also trying to put multiple plot in one page to make the pdf file smaller in size. I tried with par(mfrow) (uncommented) to handle second issue but failed.

Any help is much appreciated.

¿Fue útil?

Solución

I think you should first give an extra argument to my.ccf. For example:

my.ccf <- function(dat,year=NA)
{
   ...
  title=paste(colnames(dat)[1], "&", colnames(dat)[2], sep=" ")
  if(!is.na(year))
    title <- paste('Year', year,': CCF',title)
  ccf1 <- ccf(residuals(modx), ..., main=title)
  .....
}

Then You change your do.call to something like this :

 do.call(my.ccf, list(dat=list(ydat[[i]][,eval(c(var.do[j],'x'))]),year=i))

That' said think your year.ccf1 function is over complicated and you extremely inefficient. Try to rewrite it using outer and mapply for example.

year.ccf1 <- function(dat, var.do=c('a','b'))
{
  dat$year <- factor(format(dat$date, '%Y'))
  ydat <- split(dat,dat$year)
  outer(names(ydat),var.do,function(x,y)
    Map(function(i,j)
        do.call(my.ccf, list(dat=ydat[[i]][,c(j,'x')],year=i))
           ,x,y)
  )
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top