2012-01-18 18 views
8

Qualcuno può dirmi cosa c'è di sbagliato in questo loop if-else in R? Spesso non riesco a capire se ... altri cicli di lavoro. Ottengo un errore:Semplice loop if-else in R

if(match('SubjResponse',names(data))==NA) { 
    observed <- data$SubjResponse1 
} 
else { 
    observed <- data$SubjResponse 
} 

Nota che data è un frame di dati.

L'errore è

Error in if (match("SubjResponse", names(data)) == NA) { : 
    missing value where TRUE/FALSE needed 

risposta

2

Come notato da @DirkEddelbuettel, non è possibile testare NA in questo modo. Ma si può fare match non ritorno NA:

Utilizzando nomatch=0 e invertire la clausola if (dal 0 viene trattato come FALSE), il codice può essere semplificata. Inoltre, un altro utile linguaggio di codifica è quello di assegnare il risultato della clausola if, in questo modo non si mistype il nome della variabile in uno dei rami ...

Così mi piacerebbe scrivere in questo modo:

observed <- if(match('SubjResponse',names(data), nomatch=0)) { 
    data$SubjResponse # match found 
} else { 
    data$SubjResponse1 # no match found 
} 

a proposito, se si "spesso" problemi con if-else, si deve essere consapevoli di due cose:

  1. l'oggetto da test non deve contenere NA o NaN, o essere una stringa (carattere della modalità) o qualche altro tipo che non può essere forzato in un valore logico. Numeric is OK: 0 è FALSE qualsiasi altra cosa (ma NA/NaN) è TRUE.

  2. La lunghezza dell'oggetto deve essere esattamente 1 (un valore scalare). È possibile essere più lungo, ma poi si ottiene un avviso. Se è più breve, si ottiene un errore.

Esempi:

len3 <- 1:3 
if(len3) 'foo' # WARNING: the condition has length > 1 and only the first element will be used 

len0 <- numeric(0) 
if(len0) 'foo' # ERROR: argument is of length zero 

badVec1 <- NA 
if(badVec1) 'foo' # ERROR: missing value where TRUE/FALSE needed 

badVec2 <- 'Hello' 
if(badVec2) 'foo' # ERROR: argument is not interpretable as logical 
7

Questo non è un esempio completo, come non abbiamo i dati ma vedo questi problemi:

  1. Voi non può prova per NA con ==, è necessario is.na()
  2. Analogamente, l'output di match() e di solito viene testato per NULL o length()==0
  3. Tendo a scrivere } else { su una riga.
+0

'match' sarà sempre * * restituire un vettore della stessa lunghezza del primo argomento (' x'). Quindi in questo caso, sempre un valore scalare. – Tommy

+0

Cerchio 8.1.4 di 'The R Inferno' http://www.burns-stat.com/pages/Tutor/R_inferno.pdf –