2012-04-29 64 views
26

Chcę umieścić warunek zatrzymania wewnątrz funkcji. Warunkiem jest, aby pierwszy i drugi element pasowały idealnie w kolejności i długości.Porównywanie dwóch wektorów w instrukcji if

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

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

To dobra sytuacja, aby przejść do przodu

> A == C 

[1] TRUE FALSE TRUE FALSE 

Ponieważ istnieje jeden fałszywy ten warunek, aby zatrzymać i wyjście, że warunek doesnot trzymać w kolumnie 2 i 4-tego.

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 

Czy brakuje mi czegoś oczywistego? Mogę też wyprowadzać tam, gdzie są pozycje błędów?

Odpowiedz

39

all jest jedną z opcji:

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

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

Ale może trzeba uważać na recykling:

> 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 

The dokumentacja dla length mówi, że obecnie wyprowadza tylko liczbę całkowitą o długości 1, ale może się zmienić w przyszłości, dlatego właśnie zawinąłem test długości w all.

+4

Twoja uwaga dotycząca recyklingu jest taka, dlaczego powinieneś używać' isTRUE (all.equal (D, E)). –

+1

Patrząc na kod 'all.equal.character' był dla mnie pouczający. Ze względu na aspekt "prawie równości" dla pływających założyłem, że robił coś zabawnego również na inne rzeczy. Nie jestem pewien co z perspektywy czasu. Ale jedyną niechcianą rzeczą, którą robi, jest sprawdzanie równości wszystkich atrybutów, w tym nazw. Troszczy się też bardziej o "NA" niż mój prosty kod powyżej. – Aaron

18

Czy są identyczne?

> identical(A,C) 
[1] FALSE 

elementów, które nie zgadzają się:

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

"Identyczny" również porównuje atrybuty, które mogą być pożądane lub nie. –

+0

Nie ma tu żadnych atrybutów, ale jest to ważna kwestia. Dzięki. –

+0

'all.equal' również porównuje atrybuty, jak sądzę. – Aaron

7

I pewnie używać all.equal i which, aby uzyskać potrzebne informacje. Nie jest zalecane używanie all.equal w bloku if...else z jakiegoś powodu, więc umieszczamy go w isTRUE(). Zobacz ?all.equal dłużej:

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!") 
    } 
} 

iw użyciu:

> 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

Powodem jest to, że gdy nie są równe, nie zwraca 'FALSE', ale opis, w jaki sposób się różnią. – Aaron

+0

@Aaron - tak, rzeczywiście. Strona pomocy dla '? Identyczny' daje więcej wglądu w to ... (co czytałem po wysłaniu) – Chase