2015-07-21 5 views
9

Ich verwende eine Überlappungsfunktion über eine Liste von mehreren Dateien. Gibt es eine Möglichkeit, die Funktion der aktuellen Datei zu überspringen, ohne etwas zurückzusenden und einfach zur nächsten Datei in der Liste der Dateien zu springen?R: Überlappungsfunktion - Überspringen der aktuellen Funktionsschleife

Um genau zu sein, habe ich eine if-Anweisung, die auf eine Bedingung überprüft, und ich möchte zur nächsten Datei springen, wenn die Anweisung FALSE zurückgibt.

+1

Sie den Zustand einer Teilmenge von wählen verwenden könnte Ihre Liste und speichern Sie diese Teilmenge in einer separaten Variable, die Sie an 'lapply' liefern. – RHertel

+0

@RHertel Da sie eine Liste von Dateien und nicht ein bereits im RAM gespeichertes Datenstück verarbeiten, ist es unwahrscheinlich, dass sie die Informationen haben, um die Dateien im Voraus zu unterteilen. –

Antwort

8

lapply wird immer eine Liste mit der gleichen Länge zurückgeben wie die X. Sie können die Elemente einfach auf etwas einstellen, das Sie später herausfiltern können.

Zum Beispiel, wenn Sie die Funktion haben parsefile

parsefile <-function(x) { 
    if(x>=0) { 
    x 
    } else { 
    NULL 
    } 
} 

und Sie führen Sie es auf einem Vektor runif(10,-5,5)

result<-lapply(runif(10,-5,5), parsefiles) 

dann werden Sie Ihre Liste mit Antworten und

s NULL gefüllt

Sie können die NULL s auslassen, indem Sie ...

result[!vapply(result, is.null, logical(1))] 
+0

Das letzte Bit kann verbessert werden: 'list.condition <-! Vapply (result, is.null, logisch (1))'. Sonst eine tolle Antwort. – sdgfsdh

+0

@sdgfsdh nett ... bearbeitet, um zu reflektieren. –

+0

Vergessen Sie nicht ein '!' – sdgfsdh

0

Sie können eine benutzerdefinierte Funktion definieren, die bei Ihrem Anruf an lapply() verwendet wird. Hier ist ein Beispielcode, die eine Liste von Dateien iteriert und verarbeitet eine Datei nur dann, wenn der Name enthält nicht die Nummer 3 (ein wenig gekünstelt, aber hoffentlich wird dies den Punkt über):

files <- as.list(c("file1.txt", "file2.txt", "file3.txt")) 

fun <- function(x) { 
    test <- grep("3", x)      // check for files with "3" in their name 
    if (length(test) == 0) {     // replace with your statement here 
     // process the file here 
    } 
    // otherwise do not process the file 
} 

result <- lapply(files, function(x) fun(x)) // call lapply with custom function 
2

Wie bereits von den anderen beantwortet, glaube ich nicht, dass Sie mit der nächsten Iteration fortfahren können, ohne etwas mit der *apply Familie von Funktionen zurückgeben.

In solchen Fällen verwende ich Dean MacGregor-Methode, mit einer kleinen Änderung: Ich verwende NA anstelle von NULL, die das Filtern der Ergebnisse einfacher macht.

files <- list("file1.txt", "file2.txt", "file3.txt") 

parse_file <- function(file) { 
    if(file.exists(file)) { 
    readLines(file) 
    } else { 
    NA 
    } 
} 

results <- lapply(files, parse_file) 
results <- results[!is.na(results)] 

Eine schnelle Benchmark

res_na <- list("a", NA, "c") 
res_null <- list("a", NULL, "c") 
microbenchmark::microbenchmark(
    na = res_na[!is.na(res_na)], 
    null = res_null[!vapply(res_null, is.null, logical(1))] 
) 

zeigt, dass die NA Lösung ziemlich viel schneller als die Lösung, die NULL verwendet:

Unit: nanoseconds 
expr min lq mean median uq max neval 
    na 0 1 410.78 446 447 5355 100 
null 3123 3570 5283.72 3570 4017 75861 100