Skip to content

WriteXLS: 'object not found' error within function

2 messages · Scott Robinson, Marc Schwartz

#
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())
	}
}
#
On Feb 13, 2013, at 12:07 PM, Scott Robinson <Scott.Robinson at glasgow.ac.uk> wrote:

            
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())
}
Error in get(as.character(x), envir = envir) : 
  object 'localData' not found


localData <- split(iris, iris$Species)

test() # Works fine


rm(localData)
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