Does the ternary operator exist in R?
As if
is function in R
and returns the latest evaluation, if-else is equivalent to ?:
.
> a <- 1
> x <- if(a==1) 1 else 2
> x
[1] 1
> x <- if(a==2) 1 else 2
> x
[1] 2
The power of R is vectorization. The vectorization of the ternary operator is 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 2
Just kidding, you can define c-style ?:
:
`?` <- function(x, y)
eval(
sapply(
strsplit(
deparse(substitute(y)),
":"
),
function(e) parse(text = e)
)[[2 - as.logical(x)]])
here, you don't need to take care about brackets:
> 1 ? 2*3 : 4
[1] 6
> 0 ? 2*3 : 4
[1] 4
> TRUE ? x*2 : 0
[1] 2
> FALSE ? x*2 : 0
[1] 0
but you need brackets for assignment :(
> y <- 1 ? 2*3 : 4
[1] 6
> y
[1] 1
> y <- (1 ? 2*3 : 4)
> y
[1] 6
Finally, you can do very similar way with 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
}
}
You can get rid of brackets:
> 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] 4
These are not for daily use, but maybe good for learning some internals of R language.
Equivalent of ternary operator in R
The closest (in fact, exact) equvalent would be:
x = if (y > 2) y else 2
Or, if you want to perform a vectorised test and assignment:
x = ifelse(y > 2, y, 2)
(For y = 1 : 5
, this yields 2 2 3 4 5
.)
The important point is that, unlike in C++, (almost) every statement R is an expression with a value. C++ needs the conditional operator because if
isn’t an expression. But in R it is, and the value of an if (‹condition›) ‹true› [else ‹false›]
expression is the value of either the ‹true› or the ‹false› sub-expression, depending on whether its ‹condition› evaluates to TRUE
(and if the false
branch is missing, its value is NULL
).
Is the operator OR sensitive to the position of the argument that follows it
The difference occurs because your are breaking the line and adding spaces into your string by splitting it on to the next line and indenting it. Fix it by a) not doing that or b) creating your string with paste(..., sep="|")
grepl(paste("Radioth[ée]rapie", "Chimioth[ée]rapie",
"Radiochimioth[ée]rapie", "Cancer",
"Tumeur", "Tumoral", sep="|"),
sigaps$Titre.de.l.étude, ignore.case=TRUE)
Does Julia have a ternary conditional operator?
For inline use, a ? b : c exists, as mentioned by the previous answer. However it is worth noting that if-else-end in Julia works just like (if cond expr1 expr2) in most Lisp dialects which acts both as the if-clause and as the ternary operator. As such, if-then-else returns the return value of the expression that gets executed.
Meaning that you can write things like
function abs(x)
if x > 0
x
else
-x
end
end
and this will return what you want. You do not have to use a return statement to break the function block, you just return the value returned by the if-block.
Inline, you can write
if (x > 0) x else -x end
which will return the same thing as the ternary operator expression (x > 0) ? x : -x , but has the benefit of avoiding perl-ish ?: symbols and is generally more readable, but less chainable.
Most languages have a ternary operator separate from if-then-else because if clauses are statements, while in lisp-like languages they are expressions just like everything else and have a return value.
Does Python have a ternary conditional operator?
Yes, it was added in version 2.5. The expression syntax is:
a if condition else b
First condition
is evaluated, then exactly one of either a
or b
is evaluated and returned based on the Boolean value of condition
. If condition
evaluates to True
, then a
is evaluated and returned but b
is ignored, or else when b
is evaluated and returned but a
is ignored.
This allows short-circuiting because when condition
is true only a
is evaluated and b
is not evaluated at all, but when condition
is false only b
is evaluated and a
is not evaluated at all.
For example:
>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'
Note that conditionals are an expression, not a statement. This means you can't use statements such as pass
, or assignments with =
(or "augmented" assignments like +=
), within a conditional expression:
>>> pass if False else pass
File "<stdin>", line 1
pass if False else pass
^
SyntaxError: invalid syntax
>>> # Python parses this as `x = (1 if False else y) = 2`
>>> # The `(1 if False else x)` part is actually valid, but
>>> # it can't be on the left-hand side of `=`.
>>> x = 1 if False else y = 2
File "<stdin>", line 1
SyntaxError: cannot assign to conditional expression
>>> # If we parenthesize it instead...
>>> (x = 1) if False else (y = 2)
File "<stdin>", line 1
(x = 1) if False else (y = 2)
^
SyntaxError: invalid syntax
(In 3.8 and above, the :=
"walrus" operator allows simple assignment of values as an expression, which is then compatible with this syntax. But please don't write code like that; it will quickly become very difficult to understand.)
Similarly, because it is an expression, the else
part is mandatory:
# Invalid syntax: we didn't specify what the value should be if the
# condition isn't met. It doesn't matter if we can verify that
# ahead of time.
a if True
You can, however, use conditional expressions to assign a variable like so:
x = a if True else b
Or for example to return a value:
# Of course we should just use the standard library `max`;
# this is just for demonstration purposes.
def my_max(a, b):
return a if a > b else b
Think of the conditional expression as switching between two values. We can use it when we are in a 'one value or another' situation, where we will do the same thing with the result, regardless of whether the condition is met. We use the expression to compute the value, and then do something with it. If you need to do something different depending on the condition, then use a normal if
statement instead.
Keep in mind that it's frowned upon by some Pythonistas for several reasons:
- The order of the arguments is different from those of the classic
condition ? a : b
ternary operator from many other languages (such as C, C++, Go, Perl, Ruby, Java, JavaScript, etc.), which may lead to bugs when people unfamiliar with Python's "surprising" behaviour use it (they may reverse the argument order). - Some find it "unwieldy", since it goes contrary to the normal flow of thought (thinking of the condition first and then the effects).
- Stylistic reasons. (Although the 'inline
if
' can be really useful, and make your script more concise, it really does complicate your code)
If you're having trouble remembering the order, then remember that when read aloud, you (almost) say what you mean. For example, x = 4 if b > 8 else 9
is read aloud as x will be 4 if b is greater than 8 otherwise 9
.
Official documentation:
- Conditional expressions
- Is there an equivalent of C’s ”?:” ternary operator?
Why and when does the ternary operator return an lvalue?
Both i
and j
are glvalues (see this value category reference for details).
Then if you read this conditional operator reference we come to this point:
4) If E2 and E3 are glvalues of the same type and the same value category, then the result has the same type and value category
So the result of (i < 3) ? i : j
is a glvalue, which can be assigned to.
However doing something like that is really not something I would recommend.
Related Topics
Coding Practice in R:What Are the Advantages and Disadvantages of Different Styles
Remove Empty Elements from List with Character(0)
How Can Put Multiple Plots Side-By-Side in Shiny R
Adding Curved Flight Path Using R's Leaflet Package
Check If Each Row of a Data Frame Is Contained in Another Data Frame
One-Class Classification with Svm in R
Calculate Mean Across Rows with Na Values in R
Using Annotate to Add Different Annotations to Different Facets
Control Number of Decimal Places on Xtable Output in R
Split Date Data (M/D/Y) into 3 Separate Columns
Use Superscripts in R Axis Labels
How to Transpose a Dataframe in Tidyverse
Convert from Lowercase to Uppercase All Values in All Character Variables in Dataframe
Implementation of Parallel Coordinates
How to Suppress Automatic Table Name and Number in an .Rmd File Using Xtable or Knitr::Kable