Skip to content

write.xls

18 messages · Marc Schwartz, Spencer Graves, jim holtman +5 more

#
Hello, All:


       The "writeFindFn2xls" function in the "sos" package tries to 
write an Excel file with 3 sheets ('PackageSum2', 'findFn', 'call'). 
Unfortunately, it is often unable to do this because of configuration 
problems that are not easy to fix.  I've found 3 contributed packages 
that provide facilities to write Excel files with multiple sheets. 
Unfortunately, I can't get any of them to work consistently for me. 
Below please find test cases that illustrate the problems.  Any 
suggestions for how to solve this problem will be appreciated.


       Thanks,
       Spencer


library(dataframes2xls)

df1 <- data.frame(c1=1:2, c2=3:4, c3=5:6)
df2 <- data.frame(c21=c(10.10101010101,20, 3), c22=c(50E50,60, 3) )
outFile <- 'df12.xls'

write.xls(c(df1,df2), outFile)
# works

do.call(write.xls, list(c(df1, df2), outFile))
# Error in get(s[i]) : object 'structure(list(c1=1:2' not found

library(WriteXLS)
testPerl()
#Perl found.
#The following Perl modules were not found on this system:
#Text::CSV_XS
#If you have more than one Perl installation, be sure the correct one 
was used here.
#Otherwise, please install the missing modules. See the package INSTALL 
file for more information.

# *** NOTE:  I may be able to fix this for myself.
# *** However, I want to use this in the 'sos' package,
# *** and if it doesn't work easily for me, it may not work for others.

library(RODBC)
xlsFile <- odbcConnectExcel(outFile, readOnly=FALSE)
# NOTE:  This works with R 2.15.0 32-bit.
# However, with 64-bit, I get the following error message here:
# Error in odbcConnectExcel(outFile, readOnly = FALSE) :
#   odbcConnectExcel is only usable with 32-bit Windows

# When this works, the following 3 lines of code
#    suffice to create the outFile:
sqlSave(xlsFile, df1, tablename='sheet1')
sqlSave(xlsFile, df2, tablename='sheet2')
odbcClose(xlsFile)

sessionInfo()
#R version 2.15.0 (2012-03-30)
#Platform: x86_64-pc-mingw32/x64 (64-bit)

#locale:
#[1] LC_COLLATE=English_United States.1252
#[2] LC_CTYPE=English_United States.1252
#[3] LC_MONETARY=English_United States.1252
#[4] LC_NUMERIC=C
#[5] LC_TIME=English_United States.1252

#attached base packages:
#[1] stats     graphics  grDevices utils     datasets  methods   base

#other attached packages:
#[1] RODBC_1.3-5          WriteXLS_2.1.0       dataframes2xls_0.4.5
#
I have been using XLConnect to write multisheet Excel without any problems.

Sent from my iPad
On May 19, 2012, at 21:32, Spencer Graves <spencer.graves at structuremonitoring.com> wrote:

            
#
On 5/19/2012 7:59 PM, Jim Holtman wrote:
Thanks very much.  That looks like it will solve my problems.


       Best Wishes,
       Spencer
p.s.  findFn{sos} identified thatt for me, but for some unknown reason, 
I overlooked it.  I'll study it more carefully now.
#
On Sat, May 19, 2012 at 9:32 PM, Spencer Graves
<spencer.graves at structuremonitoring.com> wrote:
Try this:

dd <- list(df1 = df1, df2 = df2)
do.call("WriteXLS", list("dd", outFile))

or this:

do.call("WriteXLS", list(c("df1", "df2"), outFile)
#
On Sun, May 20, 2012 at 8:30 AM, Gabor Grothendieck
<ggrothendieck at gmail.com> wrote:
That was for WriteXLS.  For dataframes2xls try this:

do.call("write.xls", list(quote(c(df1, df2)), outFile))

and also check out this page:

http://rwiki.sciviews.org/doku.php?id=tips:data-io:ms_windows
#
On May 19, 2012, at 8:32 PM, Spencer Graves wrote:

            
Hi Spencer,

The INSTALL file referenced for WriteXLS is also available on CRAN:

  http://cran.r-project.org/web/packages/WriteXLS/INSTALL

The missing Perl modules cannot be provided with the CRAN package as they contain C code that must be compiled for the target platform. So one either needs to install the source Perl package from CPAN via the CLI and have a C compiler on their computer or use a Perl package manager infrastructure (eg. ActiveState Perl) that provides pre-compiled binaries for each OS and a nice GUI. The INSTALL file provides instructions for Windows, OSX and Linux as to how to address that issue.

Note that the key issue that you face is that some of the mechanisms that you are trying will be OS specific (primarily Windows), such as RODBC, since ODBC drivers for Excel will be Windows only. If you want to provide your users of sos with cross-platform functionality, then you would need to look at solutions using Perl such as WriteXLS, Java such as XLConnect or Python such as dataframes2xls. Each will have installation issues, depending upon the OS and the useR's skill sets in ensuring the presence of the required foundation. Some users may have issues in certain environments in installing Perl, Python or Java due to IT/Security issues, so something to consider.

The path of least resistance would be to simply write CSV files, which can then be opened with Excel or similar applications. It just depends upon what assumptions you want to make pertaining to maximizing your potential user base, while minimizing the installation challenges useRs may face with your package.

Regards,

Marc Schwartz
#
On May 20, 2012, at 7:30 AM, Gabor Grothendieck wrote:

            
Thanks Gabor. Note that since WriteXLS version 2.0 (2010), WriteXLS can accept a named list and write out each list element data frame to an XLS file. An example is given in ?WriteXLS:

  iris.split <- split(iris, iris$Species)
  WriteXLS("iris.split", "irissplit.xls")

You end up with a worksheet in the XLS file for each factor level in iris$Species.

Regards,

Marc Schwartz
#
Hi, Gabor:  Thanks.  I'll try that.  Spencer
On 5/20/2012 5:52 AM, Gabor Grothendieck wrote:

  
    
#
On 5/20/2012 6:47 AM, Marc Schwartz wrote:
Thanks, Marc.


       The current code first tries WriteXLS If that fails, it then 
tries RODBC.  If that fails, it writes csv files.  If I can get 
dataframes2xls and / or XLConnect to work, I plan to start with one of 
those.  These other packages are "suggests", so sos will load without them.


       Best Wishes,
       Spencer

  
    
#
On 5/20/2012 5:52 AM, Gabor Grothendieck wrote:
Hi, Gabor:  Thanks.  I think we're gaining on it, but I'm still not 
quite there.  Consider the following extension of my previous toy example:

library(dataframes2xls)

df1 <- data.frame(c1=1:2, c2=3:4, c3=5:6)
df2 <- data.frame(c21=c(10.10101010101,20, 3), c22=c(50E50,60, 3) )
outFile <- 'df12.xls'

write.xls(c(df1,df2), outFile)
# works

do.call(write.xls, list(quote(c(df1, df2)), outFile))
# works

df2x <- function(x, file)
     do.call(write.xls, list(x, file))
df2x(quote(c(df1, df2)), outFile)
# works

df2 <- function(x1, x2, file){
     x23 <- quote(c(x1, x2))
     do.call(write.xls, list(x23, file))
}
df2(df1, df2, outFile)
# Error in get(s[i]) : object 'x1' not found


       This is closer to what I need.  The answer may lie in getting the 
right "envir" argument for "do.call".  However, I haven't yet found 
something that works there.


       Thanks,
       Spencer

  
    
#
Here is what it take to write out two sheets with XLConnect


# function to write out a sheet to an EXCEL file that I use
f.writeXLSheet <-
function (data, sheet, fileToWrite, rownames = NULL)
{
    require(XLConnect)
    writeWorksheetToFile(fileToWrite, data = data, sheet = sheet,
        rownames = rownames, styleAction = XLC$STYLE_ACTION.NONE)
}

df1 <- data.frame(c1=1:2, c2=3:4, c3=5:6)
df2 <- data.frame(c21=c(10.10101010101,20, 3), c22=c(50E50,60, 3) )
outFile <- 'df12.xls'

unlink(outFile)  # make sure there is no file to start with
f.writeXLSheet(df1, 'df1', outFile)
f.writeXLSheet(df2, 'df2', outFile)

I have attached the resulting Excel file (see how far it makes it).

On Sun, May 20, 2012 at 7:15 PM, Spencer Graves
<spencer.graves at structuremonitoring.com> wrote:

  
    
#
Hi, Jim:
On 5/20/2012 4:54 PM, jim holtman wrote:
Thanks.  Unfortunately, I can't get that far:


 > library(XLConnect)
Loading required package: XLConnectJars
Loading required package: rJava
Error : .onLoad failed in loadNamespace() for 'rJava', details:
   call: stop("No CurrentVersion entry in '", key, "'! Try re-installing 
Java and make sure R and Java have matching architectures.")
   error: object 'key' not found
Error: package 'rJava' could not be loaded

 > sessionInfo()
R version 2.15.0 (2012-03-30)
Platform: x86_64-pc-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base
 >

       Best Wishes,
       Spencer
#
On Sun, May 20, 2012 at 7:15 PM, Spencer Graves
<spencer.graves at structuremonitoring.com> wrote:
Unfortunately this is getting increasingly complex due to the
non-standard evaluation done by dataframes2xls but if you want to do
it then this will do it.  We copy dataframes2xls to the current
environment and reset write.xls's environment so that it finds the
arguments.


run <- function(x1, x2, file){

   df.names <- paste0(deparse(substitute(x1)), ":::", deparse(substitute(x2)))

   # copy dataframe2xls namespace contents here & reset environment of write.xls
   here <- environment()
   ns <- asNamespace("dataframes2xls")
   for(nm in ls(ns)) here[[nm]] <- ns[[nm]]
   environment(write.xls) <- here

   x23 <- quote(c(x1, x2))
   do.call("write.xls", list(x23, file, sh.names = df.names))
}

library(dataframes2xls)

df1 <- data.frame(c1=1:2, c2=3:4, c3=5:6)
df2 <- data.frame(c21=c(10.10101010101,20, 3), c22=c(50E50,60, 3) )
outFile <- 'df12.xls'

run(df1, df2, outFile)
#
On 5/20/2012 5:37 PM, Gabor Grothendieck wrote:
<snip>
Thanks very much.  I got this to work.  However, I discovered three 
other problems with write.xls:


       (1) With "\n" in a character string in the data.frame, it fails 
to write a file, noting, "Infile name is not a valid csv file" without 
throwing an error.


       (2) With "," in a character string in the data.frame, it splits 
that element over multiple columns, thereby corrupting what is written.


       (3) It insists on quoting all all character strings.  I don't 
need or want those extraneous quotes, but I don't know how to get rid of 
them.


       I've modified the code to gsub('\n|,', ' ', strings);  this 
provides an acceptable fix to the first two problems.  I plan to ignore 
the third if I can't fix it.


       Thanks again,
       Spencer
#
Hi Spencer,

it looks like you either don't have Java installed  or the architectures of
R and your JVM don't match, i.e. your running 64-bit R (as noted from your
sessionInfo() output) but are using a 32-bit JVM. In any case installing
64-bit Java should resolve your issue.

Hope that helps.

Best regards,
Martin

--
View this message in context: http://r.789695.n4.nabble.com/write-xls-tp4630642p4630787.html
Sent from the R help mailing list archive at Nabble.com.
1 day later
#
You need to read the documentation for read.xlsx and data.frame.

In it you would discover what you have done wrong:

1. rowIndex must be an array listing the columns you wish to read not a
character value
2. colIndex must be an array listing the rows you wish to read
[Deleting these arguments will read all rows/columns which is probably what
you want]
3. colClasses="character" are you trying to read these numbers as
characters? Fortunately read.xlsx is ignoring your request since the correct
value would be "char". Just delete this argument as well.
4. row.names gets passed to data.frame. It is looking for a number or
character string indicating which column to use as rownumbers. Since you put
TRUE, that gets converted to 1 and your first variable becomes the rowname.
Certainly this is not what you want. Delete this argument as well.

I think you will find this accomplishes what you want

read<-read.xlsx("D:\\FYP\\image\\Cropped
Images\\user227\\user227forger.xlsx", 
sheetName="Sheet1")

----------------------------------------------
David L Carlson
Associate Professor of Anthropology
Texas A&M University
College Station, TX 77843-4352
#
Seems like you have a solution by now, but I didn't see:

require(xlsx)


df1 <- data.frame(c1=1:2, c2=3:4, c3=5:6)
df2 <- data.frame(c21=c(10.10101010101,20, 3), c22=c(50E50,60, 3) )
outFile <- 'df12.xls'

wb <- createWorkbook()
sh1 <- createSheet(wb,'sheet1')
addDataFrame(df1,sh1)
sh2 <- createSheet(wb,'sheet2')
addDataFrame(df2,sh2)
saveWorkbook(wb,outFile)

Which works consistently for me.

-Don