Passing arguments to xlconnect functions with ellipses

89 views Asked by At

I have a bunch of excel files in one folder, and would like to write a single function as follows:

# takes a file path and sheetname for an excel workbook, passes on additional params
getxl_sheet <- function(wb_path, sheetname, ...) {
  testbook <- XLConnect::loadWorkbook(wb_path)
  XLConnect::readWorksheet(testbook, sheet = sheetname, ...)
}  

However, when I run the following,

set.seed(31415)
x <- rnorm(15); y <- rnorm(15)
randvals <- data.frame(x=x, y=y)
XLConnect::writeWorksheetToFile("~/temp_rands.xlsx", randvals, "Sheet1")
my_vals <- getxl_sheet("~/temp_rands.xlsx", "Sheet1", endRow=5)

my_vals returns the entire 15 by 2 dataframe, as opposed to just stopping at the fifth row (likewise if I use 'endCol=1' for example, it gives both columns). On the other hand, passing additional arguments in base R hasn't been a problem:

my_plot <- function(...) {
  plot(...)
}
#my_plot(x=x, y=y, pch=16, col="blue")

works as expected. What's the problem with the function defined above to read in xlsx files? Thanks.

devtools::session_info() Session info--------------------------------------------------------------------- setting value
version R version 3.1.1 (2014-07-10) system x86_64, darwin13.1.0
ui RStudio (0.98.1062)
language (EN)
collate en_US.UTF-8
tz America/New_York

Packages------------------------------------------------------------------------- package * version date source
devtools 1.6.0.9000 2014-11-26 Github (hadley/devtools@bd9c252) rJava 0.9.6 2013-12-24 CRAN (R 3.1.0)
rstudioapi 0.1 2014-03-27 CRAN (R 3.1.0)
XLConnect * 0.2.9 2014-08-14 CRAN (R 3.1.1)
XLConnectJars * 0.2.9 2014-08-14 CRAN (R 3.1.1)

1

There are 1 answers

0
IRTFM On BEST ANSWER

The dots mechanism needs to have a function that expects dots, and unlike plot.default, readWorksheet is not designed to handle an ellipsis: You need to build some decoding into the arguments:

getxl_sheetRCshort <- function(wb_path, sheetname, ...) {
  arglist <- list(...)
  testbook <- loadWorkbook(wb_path);
  readWorksheet(testbook, sheet = sheetname, 
                endRow=arglist[['endRow']], endCol=arglist[['endCol']])
}

> my_vals <- getxl_sheet("~/temp_rands.xlsx", "Sheet1", endRow=5)
> my_vals
           x           y
1  1.6470129 -1.27323204
2 -1.1119872 -1.77141948
3 -1.5485456  1.40846809
4 -0.7483785 -0.09450125

You could make this even more general by doing matching on the entire formals() list from the readWorksheet function and there are worked examples in SO that illustrate this. Fortunately the parser is somehow able to ignore the fact that no value is passed to 'endCol'.