[R] WriteXLS: 'object not found' error within function

Marc Schwartz marc_schwartz at me.com
Wed Feb 13 19:44:12 CET 2013


On Feb 13, 2013, at 12:07 PM, Scott Robinson <Scott.Robinson at glasgow.ac.uk> wrote:

> Dear All,
> 
> I am using WriteXLS to write tables with multiple sheets with the command:
> 
> WriteXLS("tables", ExcelFileName = fileName, SheetNames = tableList, perl = "perl",
>           verbose = FALSE, Encoding = c("UTF-8", "latin1"),
>           row.names = TRUE, col.names = TRUE,
>           AdjWidth = TRUE, AutoFilter = FALSE, BoldHeaderRow = FALSE,
>           FreezeRow = 0, FreezeCol = 0,
>           envir = parent.frame())
> 
> 
> ...where "tables" is the name of a list of data.frames which are the tables to go into my sheets. I am having no problem running my code unless it is within a function in which case I get the error:
> 
> "Error in get(as.character(x), envir = envir) : object 'tables' not found"
> 
> I have checked that there is not an issue with scope using these two lines within my function immediately before calling the WriteXLS function:
> 
> print(class(tables))
> flush.console()
> [1] "list"
> 
> 
> At least I would have thought this would have ruled out any scope-related issues. Has anyone else had this problem or have any ideas why it might be happening?
> 
> Thanks,
> 
> Scott
> 
> 
> PS here is the function in full:
> 
> makeTables <- function(design, designInfo, oldMatrix, matrix, annot, tableList)
> {
> rownames(design) <- designInfo[,1]
> 
> fit <- lmFit(matrix, design)
> fit <- eBayes(fit)
> 
> tables<-list()
> 
> 	for (i in 1:length(tableList))
> 	{
> 	table <- makeTable(oldMatrix, matrix, annot, fit, tableList[i])
> 	print(paste(tableList[i], "=", sep=""))
> 	print(table)
> 	tables[[i]] <- table
> 	}
> 
> #Saving bit (set to FALSE if not using)
> saveIt <- TRUE
> 
> 	if(saveIt)
> 	{
> 	fileName <- paste0("~",paste(colnames(design)[2:length(colnames(design))], collapse = "+"),".xls")
> 
> 	print(paste("sheetnames=",length(tableList),
> 
> 	print(class(tables))
> 	flush.console()
> 
> 	WriteXLS("tables", ExcelFileName = fileName, SheetNames = tableList, perl = "perl",
>           verbose = FALSE, Encoding = c("UTF-8", "latin1"),
>           row.names = TRUE, col.names = TRUE,
>           AdjWidth = TRUE, AutoFilter = FALSE, BoldHeaderRow = FALSE,
>           FreezeRow = 0, FreezeCol = 0,
>           envir = parent.frame())
> 	}
> }


Hi Scott,

In the call to WriteXLS() within your function, leave out the final argument line 'envir = parent.frame()'. That is causing WriteXLS() to look for "tables" in the environment in which your function makeTables() is being called and of course, "tables" does not exist there, but only within the scope of makeTables(). Leaving the argument out allows WriteXLS() to look for "tables" within the environment in which it is called.

This is a nuance when using environments within functions. The same thing commonly happens when folks use the 'subset' argument with modeling functions that are themselves called within a function body.

As an example with WriteXLS():

test <- function() {
   localData <- split(iris, iris$Species)
   WriteXLS("localData", "LocalData.xls", envir = parent.frame())
}


> test()
Error in get(as.character(x), envir = envir) : 
  object 'localData' not found


localData <- split(iris, iris$Species)

test() # Works fine


rm(localData)


> test()
Error in get(as.character(x), envir = envir) : 
  object 'localData' not found


test <- function() {
  localData <- split(iris, iris$Species)
  WriteXLS("localData", "LocalData.xls")
}


test() # Works fine


Hope that clarifies.

Regards,

Marc Schwartz



More information about the R-help mailing list