2015-05-15 13 views
5

Il mio attuale obiettivo di apprendimento in R è quello di evitare i loop for. Molto spesso devo elencare i file in una directory (o cicli attraverso le directory) per eseguire diverse operazioni su quei file.R - Come evitare il loop nella lista dei file

Un esempio del mio compito è il seguente: Devo richiamare un'applicazione di sistema denominata cdo per unire due file. La sintassi di questo comando è, diciamo: cdo merge input_file1 input_file2 output_file.

Il mio codice R attuale assomiglia a questo:

# set lists of files 
u.files <- c("uas_Amon_ACCESS1-3.nc", "uas_Amon_CMCC-CESM.nc", "uas_Amon_CMCC-CESM.nc") 
v.files <- c("vas_Amon_ACCESS1-3.nc", "vas_Amon_CMCC-CESM.nc", "vas_Amon_CMCC-CESM.nc") 

for (i in 1:length(u.files)) { 

    # set input file 1 to use on cdo 
    input1 <- paste(u.files[i], sep='') 

    # set input file 2 to use on cdo 
    input2 <- paste(v.files[i], sep='') 

    # set output file to use on cdo 
    output <- paste('output_', u.files[i], sep='') 

    # assemble the command string 
    comm <- paste('cdo merge', input1, input2, output, collapse='') 

    # submit the command 
    system(comm) 

} 

che funziona male, anche se non sembra che il bene.

Tuttavia, spesso sento le persone dire che i loop for in R sono lenti e dovrebbero essere evitati il ​​più possibile.

C'è un modo per evitare i cicli for e rendere il codice più efficiente/leggibile in casi come questo?

+1

Qui, si utilizza R solo per eseguire uno strumento di sistema (ad es. Cdo). Dal mio punto di vista, potrebbe essere più efficiente utilizzare direttamente uno script di shell. –

+0

@Pascal, questo codice è in realtà un estratto. In realtà ho molto più roba andando dentro il loop fino a quando non arriva a questo punto. Ma tutti gli altri comandi implicano anche l'indicizzazione nel ciclo, quindi se capisco la logica dietro l'eliminazione del ciclo sarei in grado di usarlo nel mio script reale. – thiagoveloso

+1

Ho appena segnalato che è possibile semplificare il codice R rimuovendo tutte le chiamate di sistema non necessarie, tramite il preprocessing. Ma naturalmente, dipende da te. –

risposta

2

Questo è più R-idiomatica:

u.files <- c("uas_Amon_ACCESS1-3.nc", "uas_Amon_CMCC-CESM.nc", "uas_Amon_CMCC-CESM.nc") 
v.files <- c("vas_Amon_ACCESS1-3.nc", "vas_Amon_CMCC-CESM.nc", "vas_Amon_CMCC-CESM.nc") 
output <- paste('output_', u.files, sep='') 
comm <- paste('cdo merge', u.files, v.files, output) 
lapply(comm,system) 

Ricordate che la maggior parte delle funzioni sono vettorializzare in R, in modo da non dover chiamare paste per ogni iterazione del ciclo. Alla fine si ottiene un vettore di comandi ed eseguito uno ad uno tramite lapply nell'ultima riga.

Problemi correlati