Writing data frames into multiple excel sheets
Post date: Mar 28, 2014 10:03:43 PM
If you want to write data frames into excel files (.xls), each data frame for each sheet. Here is what you want
rm
(list = setdiff(ls(), lsf.str())) # ==================================================== # write a dataframe to excel file # ==================================================== df2xls <- function(L, file, sh.names = "default", formats = "default", t.formats = FALSE, fnt.names = "Helvetica", fnt.metr = "default", col.widths = 48, col.names = TRUE, row.names = FALSE, to.floats = "default", python = "python", py.script = "default", sh.return = FALSE) { # This function is just a wrapper of the original # function 'dataframes2xls::write.xls' # -- extract the dataframe from list L -- df.names <- names(L) for (nm in df.names) { assign(x=nm, value=as.data.frame(L[[nm]]), envir=.GlobalEnv) } # -- list all the extracted dataframe -- df_list <- paste(df.names,collapse=',') # --- if sheet.names is not specified --- if (sh.names=="default") { sh.names <- df_list } # --- write to excel file --- my.command <- " dataframes2xls::write.xls( x=_DF_LIST, file=file, sh.names = sh.names, formats = formats, t.formats = t.formats, fnt.names = fnt.names, fnt.metr = fnt.metr, col.widths = col.widths, col.names = col.names, row.names = row.names, to.floats = to.floats, python = python, py.script = py.script, sh.return = sh.return ) " my.command <- gsub(pattern='_DF_LIST', replacement=paste('c(',df_list,')',sep=''), x=my.command) eval(parse(text = my.command)) # --- erase the variables after used --- eval(parse(text=paste('rm(',df_list,',envir=.GlobalEnv)'))) # ------------------------------------------------------------ # Note: Normally, variables created in a function would be local. # However, in this case, we will have to call package 'dataframes2xls' # from python, which means the local variables would not be found. # Therefore, in this function we have to assign the new variables in # global environment, that is, envir=.GlobalEnv. Afterward, the variables are # removed from the global environment as well. # ------------------------------------------------------------ return(T) } # ================================================ # get the type of variable # ================================================ typeVar <- function(x) { # --- check if an entry is integer or not --- IsInteger <- function(x) { return(x%%1 == 0) } # --- main part starts here --- if (class(x) %in% c('numeric')) { if (all(IsInteger(x))) { return('integer') } else { if (all(abs(x)>=0 & abs(x)<=1)) { return('decimal0_1') } else { return('decimal') } } } else { return(class(x)) } } # ================================================ # recommended format for each dataframe df # ================================================ getFormat <- function(df) { # ----- function to output format for each column ----- varFormat <- function(var.type) { switch(var.type, 'integer'={out='x:0'}, 'decimal'={ out='x:0.0000' }, 'decimal0_1'={ out='x:0.00%' }, 'factor'={out='x:general'}, 'character'={out='x:general'}) return(out) } # ----- figure the format for each column ----- col.type <- sapply(df,typeVar) var.format <- sapply(col.type,varFormat) for (i in 1:length(var.format)) { var.format[i] <-gsub(pattern='x',replacement=i-1,x=var.format[i]) } return(paste(var.format,collapse='::')) } # ================================ # DEMO # ================================ # ====== data preparation ====== df1 <- data.frame(x=c(1,2,3), y=c('a','b','c')) df2 <- data.frame(x=c(1,2,3,4), y=c('a','b','c','z'), z=c(0.1,0.23,0.343434,0.390223132)) # -- put all dataframes into a list -- L <- NULL L$p1 <- df1 L$p2 <- df2 # -- [optional] you might want to assign sheet names -- sheet.names <- 'page1,page2' # -- specify the python interpretor -- # Note that the package dataframes2xls does not work with python3.X # By default I set it to 'python', but in my machine 'python' = python3.3, # which does not work. # That's why I have to use '/Anaconda/python' which is still python 2.7 python.interpretor <- '/Anaconda/python' # -- your excel file name -- outname <- 'myxlsoutput.xls' # -- simply run it! -- df2xls(L, file=outname, python = python.interpretor) # -- a fancier example -- # we can format the output and name the sheets fmts = "0:0::1:general,0:0::1:general::2:0.0%" df2xls(L, file=outname, sh.names = sheet.names, formats = fmts, python = python.interpretor) # -- a more automatic way to get format -- fmts = paste(getFormat(df1), getFormat(df2),sep=',') df2xls(L, file=outname, sh.names = sheet.names, formats = fmts, python = python.interpretor)
Created by Pretty R at inside-R.org
--------