2016-09-07 19 views
3

Ich suche nach einer einfachen Möglichkeit, auf die nächste Iteration in einer for-Schleife in R, wenn die Operation innerhalb der for-Schleife Fehler.Wenn Fehler, nächste Iteration in einer for-Schleife in R

Ich habe einen einfachen Fall unten neu erstellt:

for(i in c(1, 3)) { 
    test <- try(i+1, silent=TRUE) 
    calc <- if(class(test) %in% 'try-error') {next} else {i+1} 
    print(calc) 
} 

Das gibt mir richtig die folgenden Werte berechnet.

[1] 2 
[1] 4 

aber sobald ich den Vektor in i ändern, um einen nicht-numerischen Wert umfassen:

for(i in c(1, "a", 3)) { 
    test <- try(i+1, silent=TRUE) 
    calc <- if(class(test) %in% 'try-error') {next} else {i+1} 
    print(calc) 
} 

Diese for-Schleife funktioniert nicht. Ich hatte auf die gleichen Werte wie oben mit dem Vektor, der den nicht-numerischen Wert in i ausschließt, gehofft.

versuchte ich TryCatch wie folgt verwendet:

for(i in c(1, "a", 3)) { 
    calc <- tryCatch({i+1}, error = function(e) {next}) 
    print(calc) 
} 

Allerdings bekomme ich folgende Fehler:

Error in value[[3L]](cond) : no loop for break/next, jumping to top level 

Könnte jemand bitte helfen Sie mir zu verstehen, wie ich dies einer for-Schleife erreichen könnte in R?

+3

Sie könnten untersuchen, was 'c (1," a ", 3)' tatsächlich ist. Ich denke, Sie glauben, dass nur das mittlere Element Charakter ist, aber das ist falsch. – Dason

+2

Ich bin mir nicht sicher, warum Sie das versuchen, obwohl. Ist das ein vereinfachtes Beispiel? Wenn dies nicht der Fall ist, dann wird die Verwendung von 'as.numeric' auf dem Eingabevektor die Zeichen zu NA machen. Spielen Sie damit herum 'as.numeric (c (1," k "," 3 ")) + 1' – Dason

+0

@Dason Ich interessiere mich eher für die Fehlerbehandlung des Kontrollflusses innerhalb des for-loop-Beispiels, wie dies gerade ist ein vereinfachter Fall eines größeren Drehbuchs, das ich habe. Ich habe nur die Definition von Vektor in i verletzt, indem ich ein Zeichenelement gesetzt habe, um ein Szenario neu zu erstellen, das einen "Fehler" auswirft. Hoffe das klärt meine Frage. – ed0reddie

Antwort

1

Wie Deron bemerkte, ist ein atomarer Vektor wirklich nicht die beste Art gemischte Datentypen zu speichern. Listen sind dafür. Betrachten Sie folgendes:

l = list(1, "sunflower", 3) 

for(i in seq_along(l)) { 
    this.e = l[[i]] 
    test <- try(this.e + 1, silent=TRUE) 
    calc <- if(class(test) %in% 'try-error') {next} else {this.e + 1} 
    print(calc) 
} 

[1] 2 
[1] 4 

Mit anderen Worten, Ihre ehemalige Schleife "arbeitete". Es ist nur immer fehlgeschlagen und ging zur nächsten Iteration.

0

Hier ist eine Lösung, die das "purr" -Paket verwendet, das hilfreich sein könnte. Es geht durch die Liste oder Vektor und gibt die Elemente, die Fehler

#Wrap the function you want to use in the adverb "safely" 
safetest <- safely(function(x){ifelse(is.na(as.numeric(x)), 
            x+1, 
            as.numeric(x)+1)}) 

myvect<-c(1,"crumbs",3) #change to list if you want a list 

#Use the safe version to find where the errors occur 
check <- myvect %>% 
    map(safetest) %>% 
    transpose %>% .$result %>% 
    map_lgl(is_null) 

myvect[check] 

#This returns the results that did not through an error 
#first remove NULL elements then flatten to double. 
#The two flatten expresiion can be replaced by a single unlist 
myvect %>% 
    map(safetest) %>% 
    transpose %>% .$result %>% 
    flatten()%>%flatten_dbl() 

siehe https://blog.rstudio.org/2016/01/06/purrr-0-2-0/ für das ursprüngliche Beispiel verursacht.

Verwandte Themen