2012-09-05 9 views
5

Da this post Ho uno script che esporta un elenco come fogli di lavoro separati in un file Excel (codice come di seguito). Ora vorrei avvolgerlo in una comoda funzione per riprodurre questo comportamento fornendo il nome dell'elenco di input e il nome del file di output.Funzione per salvare l'elenco R in fogli di lavoro Excel separati

dati del campione:

var1 <- list('2003' = 1:3, '2004' = c(4:3), '2005' = c(6,4,1), '2006' = 1:4) 

script corrente:

require("XLConnect") 
wb <- loadWorkbook("var1.xlsx", create = TRUE) 
createSheet(wb, names(var1)) 
writeWorksheet(wb, var1, names(var1),header=FALSE) 
saveWorkbook(wb) 

Disclaimer:Mentre io arrossisco a chiedere una semplice domanda così, sono sicuro che molti altri visitatori a SO piacerà trovare queste informazioni qui; 7)

EDIT :: pronto per l'uso funzione:

save.excel <-function(.list, default = 'var1', path = ''){ 
    require("XLConnect") 
    .name <- as.list(match.call())[2] 
    if(is.language(.name[[1]])) wb_name <- paste0(paste0(path, default, collapse = '/'), '.xlsx') 
    if(is.symbol(.name[[1]])) wb_name <- paste0(paste0(path, as.character(.name), collapse = '/'), '.xlsx') 
    wb <- loadWorkbook(wb_name, create = TRUE) 
    createSheet(wb, names(.list)) 
    writeWorksheet(wb,.list, names(.list),header=FALSE) 
    saveWorkbook(wb) 
    } 

L'unica differenza rispetto alla soluzione qui di seguito è che ho aggiunto XLConnect come libreria richiesto all'interno della funzione, nel caso non lo fallo manualmente prima; 7)

+0

Non ci sono data.frame nel codice di esempio, solo una lista con nome – mnel

+0

Hai letto il file della guida per 'writeNamedRegion' – mnel

+0

@mnel, grazie. Seconda volta in 2 giorni consecutivi che faccio quel refuso. ** arrossire ** – dmvianna

risposta

6

Questo non è stato verificato, poiché XLConnect non verrà installato sulla mia macchina. ma qualcosa di simile al seguente potrebbe funzionare

approccio semplice

una funzione con due argomenti

  • my_list - lista che si desidera esportare elementi di fogli di lavoro come separati
  • wb_name - il nome del la cartella di lavoro

La funzione è simile a questa

write_list <-function(my_list, wb_name = 'var1.xlsx') {  
    wb <- loadWorkbook(wb_name, create = TRUE) 
    createSheet(wb, names(my_list)) 
    writeWorksheet(wb, my_list, names(my_list),header=FALSE) 
    saveWorkbook(wb) 
} 

opzione di fantasia che utilizzerà il nome della lista

Se si desidera utilizzare il nome del list per creare il file, allora ci si può divertire con match.call, is.symbol e is.language. Dettagli del perché si esegue questa operazione sono al di sotto

write_list_name <-function(.list, default = 'var1', path = ''){ 
    .name <- as.list(match.call())[2] 
    if(is.language(.name[[1]])){ 
    wb_name <- sprintf("%s/%s.xlsx", path, default) 
    } 
    if(is.symbol(.name[[1]])) { 
    wb_name <- sprintf("%s/%s.xlsx", path, as.character(.name)) 
    } 
    wb <- loadWorkbook(wb_name, create = TRUE) 
    createSheet(wb, names(.list)) 
    writeWorksheet(wb,.list, names(.list),header=FALSE) 
    saveWorkbook(wb) 
    } 

il is.language/is.symbol/match.call accordo con le due situazioni

write_list_name(var1) 

#in which case .name[[1]] is the symbol var1 

e

write_list_name(list(n=2:3)) 
# in which case .name[[1]] is list(n=2:3), and class language 
# a file called list(n=2:3).xlsx would be not ideal, hence the `default` argument. 
+1

Deducendo il nome del foglio di lavoro dal nome dell'oggetto (se possibile), imo distrae un po 'dal problema dell'OP. In un esempio più semplice e illustrativo, l'utente può specificare il nome del file xlsx, cioè utilizzare 'wb_name' come argomento. –

+1

Inoltre, è possibile sostituire il doppio codice 'paste0' con una singola chiamata a' sprintf': ad es. 'sprintf ("% s /% s.xlsx ", percorso, predefinito)'. –

+0

Sì, è forse la doratura del giglio o la cottura del budino (trova l'idioma appropriato). Ho modificato la risposta – mnel

2

Oltre alla soluzione di @mnel, ecco alcune informazioni generali sulle funzioni.

In generale, una funzione sembra qualcosa di simile:

function_name = function(input_a, input_b) { 
    c = input_a * 2 
    d = do_something(input_b) 
    return(list(c, d)) 
} 

dove input_a, e input_b sono gli argomenti di input, e list(c, d) è il valore di ritorno. Questo valore restituito viene assegnato all'oggetto che si trova sul lato sinistro della = quando chiama la funzione:

out_a = function_name(a, b) 

nota che nel corpo della funzione di function_name, a e b sostituire input_a e input_b. Il fatto che a sia collegato a input_a viene eseguito in base all'ordine degli argomenti. argomenti In alternativa, si può usare nome:

out_a = function(input_a = a, input_b = b) 

Questo rende la funzione di chiamata in modo più leggibile, a mio parere, soprattutto per i nomi delle funzioni e degli argomenti ben scelti.

Problemi correlati