Comme la question se pose, y a-t-il une séquence de contrôle dans R similaire à l' opérateur ternaire de C ? Si oui, comment l'utilisez-vous? Merci!
if (x>1) y=2 else y=3. Ecrire y=une fois a un certain attrait.
                Comme la question se pose, y a-t-il une séquence de contrôle dans R similaire à l' opérateur ternaire de C ? Si oui, comment l'utilisez-vous? Merci!
if (x>1) y=2 else y=3. Ecrire y=une fois a un certain attrait.
                Réponses:
De même que iffunction in Ret renvoie la dernière évaluation, if-else est équivalent à ?:.
> a <- 1
> x <- if(a==1) 1 else 2
> x
[1] 1
> x <- if(a==2) 1 else 2
> x
[1] 2La puissance de R est la vectorisation. La vectorisation de l'opérateur ternaire est ifelse:
> a <- c(1, 2, 1)
> x <- ifelse(a==1, 1, 2)
> x
[1] 1 2 1
> x <- ifelse(a==2, 1, 2)
> x
[1] 2 1 2Je plaisante, vous pouvez définir le style c ?::
`?` <- function(x, y)
    eval(
      sapply(
        strsplit(
          deparse(substitute(y)), 
          ":"
      ), 
      function(e) parse(text = e)
    )[[2 - as.logical(x)]])ici, vous n'avez pas besoin de vous soucier des parenthèses:
> 1 ? 2*3 : 4
[1] 6
> 0 ? 2*3 : 4
[1] 4
> TRUE ? x*2 : 0
[1] 2
> FALSE ? x*2 : 0
[1] 0mais vous avez besoin de crochets pour l'affectation :(
> y <- 1 ? 2*3 : 4
[1] 6
> y
[1] 1
> y <- (1 ? 2*3 : 4)
> y
[1] 6Enfin, vous pouvez faire de manière très similaire avec c:
`?` <- function(x, y) {
  xs <- as.list(substitute(x))
  if (xs[[1]] == as.name("<-")) x <- eval(xs[[3]])
  r <- eval(sapply(strsplit(deparse(substitute(y)), ":"), function(e) parse(text = e))[[2 - as.logical(x)]])
  if (xs[[1]] == as.name("<-")) {
    xs[[3]] <- r
        eval.parent(as.call(xs))
  } else {
    r
  }
}       Vous pouvez vous débarrasser des crochets:
> y <- 1 ? 2*3 : 4
> y
[1] 6
> y <- 0 ? 2*3 : 4
> y
[1] 4
> 1 ? 2*3 : 4
[1] 6
> 0 ? 2*3 : 4
[1] 4Ce ne sont pas pour un usage quotidien, mais peut-être bon pour apprendre certains éléments internes du langage R.
Comme tout le monde l'a dit, utilisez ifelse, mais vous pouvez définir des opérateurs de sorte que vous ayez presque la syntaxe d'opérateur ternaire.
`%?%` <- function(x, y) list(x = x, y = y)
`%:%` <- function(xy, z) if(xy$x) xy$y else z
TRUE %?% rnorm(5) %:% month.abb
## [1]  0.05363141 -0.42434567 -0.20000319  1.31049766 -0.31761248
FALSE %?% rnorm(5) %:% month.abb
## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
# or, more generally
condition %?% value1 %:% value2Cela fonctionne réellement si vous définissez les opérateurs sans les %signes, donc vous pourriez avoir
`?` <- function(x, y) if(x) y[[1]] else y[[2]]
`:` <- function(y, z) list(y, z)
TRUE ? rnorm(5) : month.abb
## [1]  1.4584104143  0.0007500051 -0.7629123322  0.2433415442  0.0052823403
FALSE ? rnorm(5) : month.abb
## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"(Cela fonctionne car la priorité de :est inférieure à ?.)
Malheureusement, cela rompt alors les opérateurs d'aide et de séquence existants.
Juste comme une farce, vous pouvez redéfinir l' ?opérateur pour (presque) travailler comme l'opérateur ternaire (CECI EST UNE MAUVAISE IDÉE):
`?` <- function(x, y) { y <-substitute(y); if(x) eval(y[[2]], parent.frame()) else eval(y[[3]], parent.frame()) }
x <- 1:3
length(x) ? (x*2) : 0
x <- numeric(0)
length(x) ? (x*2) : 0
for(i in 1:5) cat(i, (i %% 2) ? "Odd\n" : "Even\n")... Mais vous devez mettre les expressions entre parenthèses car la priorité par défaut n'est pas comme en C.
N'oubliez pas de restaurer l'ancienne fonction d'aide lorsque vous avez terminé de jouer:
rm(`?`)Je voudrais jeter un oeil à la ifelsecommande. Je l'appellerais encore mieux car il est également vectorisé. Un exemple utilisant le jeu de données cars:
> cars$speed > 20
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
[49]  TRUE  TRUE
> ifelse(cars$speed > 20, 'fast', 'slow')
 [1] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[11] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[21] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[31] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow"
[41] "slow" "slow" "slow" "fast" "fast" "fast" "fast" "fast" "fast" "fast"ifelseavec votre exemple? ;)
                    Votre lien pointe vers une ifdéclaration.
> x <- 1
> if(x < 2) print("Less than") else print("Greater than")
[1] "Less than"Si votre variable d'entrée est un vecteur, cela ifelsepourrait être plus approprié:
> x <- 1:3
> ifelse(x<=2, "Less than or equal", "Greater than")
[1] "Less than or equal" "Less than or equal" "Greater than"   Pour accéder à la page d'aide de if, vous devez intégrer les ifbackticks:
?`if`La page d'aide pour ifelseest à:
`?ifelse`print(if (x<2) "Less than" else "Greater than")
                    Cela n'existe pas explicitement, mais vous pouvez le faire:
set.seed(21)
y <- 1:10
z <- rnorm(10)
condition1 <- TRUE
x1 <- if(condition1) y else zou
condition2 <- sample(c(TRUE,FALSE),10,TRUE)
x2 <- ifelse(condition2, y, z)La différence entre les deux est que condition1doit être un vecteur logique de longueur 1, tandis que condition2doit être un vecteur logique de la même longueur que x, y, et z. Le premier retournera soit you z(l'objet entier), tandis que le second renverra l'élément correspondant de y( condition2==TRUE) ou z( condition2==FALSE).
Notez également que ifelsesera plus lent que if/ elsesi condition, yet zsont tous les vecteurs de longueur 1.
if fonctionne comme un ifelse non visualisé s'il est utilisé de la manière suivante:
`if`(condition, doIfTrue, doIfFalse)L'avantage d'utiliser ceci par rapport à ifelse est lorsque la vectorisation est gênante (c'est-à-dire que j'ai des choses scalaires booléennes et liste / vecteur en conséquence)
ifelse(TRUE, c(1,2), c(3,4))
[1] 1
`if`(TRUE, c(1,2), c(3,4))
[1] 1 2
ifelse, ou simplement une forme plus compacte?