Question

J'ai trouvé des déclarations IfElse de R être assez pratique de temps en temps. Par exemple:

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

Mais je suis un peu confus par le comportement suivant.

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

Est-ce un choix de conception qui est au-dessus de mon paygrade?

Était-ce utile?

La solution

La documentation pour les Etats ifelse:

  

ifelse renvoie une valeur ayant le même   forme que test qui est rempli de   éléments choisis parmi une ou l'autre ou yes   no selon que l'élément   de test est TRUE ou FALSE.

Puisque vous passez des valeurs de test de longueur 1, vous obtenez des résultats de longueur 1. Si vous passez des vecteurs de test plus, vous obtiendrez des résultats plus:

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

ifelse est destiné à l'usage spécifique de l'essai d'un vecteur de booléens et retourner un vecteur de la même longueur, rempli d'éléments prélevés sur le (vecteur) yes et arguments no.

Il est une confusion commune, à cause du nom de la fonction, à utiliser quand vraiment vous voulez juste une construction if () {} else {} normale à la place.

Autres conseils

Je parie que vous voulez une simple déclaration de if au lieu de ifelse - dans R, if est non seulement une structure de contrôle de flux, il peut retourner une valeur:

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

Notez que vous pouvez contourner le problème si vous attribuez le résultat à l'intérieur du 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

ouais, je pense ifelse () est vraiment conçu pour quand vous avez un grand long vecteur de tests et que vous voulez cartographier chacun à l'une des deux options. Par exemple, je fais souvent des couleurs pour complot () de cette façon:

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

Si vous aviez un grand long vecteur de tests mais je voulais paires pour les sorties, vous pouvez utiliser sapply() ou de plyr de llply() ou quelque chose, peut-être.

Voici une approche similaire à celle proposée par Cath, mais il peut fonctionner avec des vecteurs pré-existants affectés

Il est basé sur l'utilisation du get() comme ceci:

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

Parfois, l'utilisateur a juste besoin d'une déclaration de switch au lieu d'un ifelse. Dans ce cas:

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

(ce qui est une autre option de syntaxe de la réponse de Ken Williams)

utiliser `if`, par exemple,

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

Dans votre cas, l'utilisation de if_else dplyr aurait été utile: if_else est plus stricte que ifelse et jette une erreur pour votre cas:

library(dplyr)
if_else(TRUE,c(1,2),c(3,4))
#> `true` must be length 1 (length of `condition`), not 2
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top