2012-04-29 9 views
26

Voglio mettere la condizione di arresto all'interno di una funzione. La condizione è che se il primo e il secondo elemento dovessero combaciare perfettamente in ordine e lunghezza.Confronto di due vettori in una istruzione if

A <- c("A", "B", "C", "D") 
B <- A 
C <- c("A", "C", "C", "E") 

> A == B 
[1] TRUE TRUE TRUE TRUE 

Questa è una buona situazione per andare avanti

> A == C 

[1] TRUE FALSE TRUE FALSE 

Poiché non v'è una falsa questa condizione di fermarsi e di uscita che la condizione doesnot stretta a 2 e 4 esima colonna.

if (A != B) { 
      stop("error the A and B does not match at column 2 and 4"} else { 
      cat ("I am fine") 
       } 
Warning message: 
In if (A != B) (stop("error 1")) : 
    the condition has length > 1 and only the first element will be used 

Mi manca qualcosa di ovvio? Posso anche scrivere dove sono posizionate le posizioni di errore?

risposta

39

all è un'opzione:

> A <- c("A", "B", "C", "D") 
> B <- A 
> C <- c("A", "C", "C", "E") 

> all(A==B) 
[1] TRUE 
> all(A==C) 
[1] FALSE 

Ma potrebbe essere necessario guardare fuori per il riciclaggio:

> D <- c("A","B","A","B") 
> E <- c("A","B") 
> all(D==E) 
[1] TRUE 
> all(length(D)==length(E)) && all(D==E) 
[1] FALSE 

Il documentazione per length dice che attualmente produce solo un numero intero di lunghezza 1, ma che potrebbe cambiare in futuro, ecco perché ho concluso il test di lunghezza in all.

+4

La tua cautela sul riciclaggio è il motivo per cui dovresti usare' isTRUE (all.equal (D, E)) '. –

+1

Guardare il codice per 'all.equal.character' è stato illuminante per me. A causa dell'aspetto "quasi-uguaglianza" per i float, ho pensato che avrebbe fatto qualcosa di divertente anche per altre cose. Non sono sicuro di cosa, in retrospettiva. Ma l'unica cosa forse indesiderata che fa è controllare l'uguaglianza di tutti gli attributi, compresi i nomi. Ci vuole anche più attenzione con 'NA's rispetto al mio semplice codice sopra. – Aaron

18

Sono identici?

> identical(A,C) 
[1] FALSE 

Quali elementi non sono d'accordo:

> which(A != C) 
[1] 2 4 
+4

'identico' confronta anche gli attributi, che possono o non possono essere desiderabili. –

+0

Nessun attributo è presente qui, ma questo è un punto importante. Grazie. –

+0

'all.equal' confronta anche gli attributi, credo. – Aaron

7

probabilmente sarei uso all.equal e which per ottenere le informazioni desiderate. Si sconsiglia di utilizzare all.equal in un blocco if...else per qualche motivo, quindi lo avvolgiamo in isTRUE(). Vedere ?all.equal per più:

foo <- function(A,B){ 
    if (!isTRUE(all.equal(A,B))){ 
    mismatches <- paste(which(A != B), collapse = ",") 
    stop("error the A and B does not match at the following columns: ", mismatches) 
    } else { 
    message("Yahtzee!") 
    } 
} 

e in uso:

> foo(A,A) 
Yahtzee! 
> foo(A,B) 
Yahtzee! 
> foo(A,C) 
Error in foo(A, C) : 
    error the A and B does not match at the following columns: 2,4 
+1

La ragione è che quando non sono uguali non restituisce 'FALSE' ma una descrizione di come differiscono. – Aaron

+0

@ Aaron - sì, davvero. La pagina di aiuto per '? Identici' fornisce ulteriori informazioni su questo ... (che ho esaminato dopo la pubblicazione) – Chase