Scott Robinson
2013-Feb-13 18:07 UTC
[R] WriteXLS: 'object not found' error within function
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()) } }
Marc Schwartz
2013-Feb-13 18:44 UTC
[R] WriteXLS: 'object not found' error within function
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