Domanda

Ho trovato le dichiarazioni IfElse di R di essere piuttosto utile di tanto in tanto. Ad esempio:

ifelse(TRUE,1,2)
# [1] 1
ifelse(FALSE,1,2)
# [1] 2

Ma io sono un po 'confusa dal seguente comportamento.

ifelse(TRUE,c(1,2),c(3,4))
# [1] 1
ifelse(FALSE,c(1,2),c(3,4))
# [1] 3

Si tratta di una scelta progettuale che è sopra la mia paygrade?

È stato utile?

Soluzione

La documentazione per gli stati ifelse:

  

ifelse restituisce un valore con la stessa   forma come test che viene riempito con   elementi selezionati da uno o yes   no seconda che l'elemento   di test è TRUE o FALSE.

Dal momento che si sta passando valori di prova di lunghezza 1, si stanno ottenendo risultati di lunghezza 1. Se si passa vettori di prova più lunghi, si ottengono risultati più lunghi:

> ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4))
[1] 1 4

Quindi ifelse è destinato per lo scopo specifico di testare un vettore di booleani e restituendo un vettore della stessa lunghezza, riempita con elementi presi dal (vettore) yes e argomenti no.

Si tratta di una confusione comune, a causa del nome della funzione, utilizzare questo, quando in realtà si vuole solo una normale costruzione if () {} else {} invece.

Altri suggerimenti

Scommetto che si desidera una semplice dichiarazione if invece di ifelse - in R, if non è solo una struttura di controllo del flusso, può restituire un valore:

> if(TRUE) c(1,2) else c(3,4)
[1] 1 2
> if(FALSE) c(1,2) else c(3,4)
[1] 3 4

Si noti che è possibile aggirare il problema se si assegna il risultato all'interno della ifelse:

ifelse(TRUE, a <- c(1,2), a <- c(3,4))
a
# [1] 1 2

ifelse(FALSE, a <- c(1,2), a <- c(3,4))
a
# [1] 3 4

sì, penso IfElse () è in realtà progettato per quando si ha un gran lunga vettore di test e si desidera mappare ciascuno per una delle due opzioni. Per esempio, faccio spesso colori per la trama () in questo modo:

plot(x,y, col = ifelse(x>2,  'red', 'blue'))

Se si ha un gran lunga vettore di test, ma voleva coppie per le uscite, è possibile utilizzare sapply() o plyr di llply() o qualcosa del genere, forse.

Ecco un approccio simile a quello suggerito da Cath, ma può funzionare con i vettori pre-assegnato esistenti

E 'basato su utilizzando il get() in questo modo:

a <- c(1,2)
b <- c(3,4)
get(ifelse(TRUE, "a", "b"))
# [1] 1 2

A volte l'utente ha solo bisogno di una dichiarazione switch invece di un ifelse. In tal caso:

condition <- TRUE
switch(2-condition, c(1, 2), c(3, 4))
#### [1] 1 2

(che è un'altra opzione la sintassi della risposta di Ken Williams)

usare `if`, per esempio

> `if`(T,1:3,2:4)
[1] 1 2 3

Nel tuo caso, utilizzando if_else da dplyr sarebbe stato utile: if_else è più severe rispetto ifelse, e getta un errore per il vostro caso:

library(dplyr)
if_else(TRUE,c(1,2),c(3,4))
#> `true` must be length 1 (length of `condition`), not 2
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top