Why can't R's ifelse statements return vectors?
The documentation for ifelse
states:
ifelse
returns a value with the same
shape astest
which is filled with
elements selected from eitheryes
or
no
depending on whether the element
oftest
isTRUE
orFALSE
.
Since you are passing test values of length 1, you are getting results of length 1. If you pass longer test vectors, you will get longer results:
> ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4))
[1] 1 4
So ifelse
is intended for the specific purpose of testing a vector of booleans and returning a vector of the same length, filled with elements taken from the (vector) yes
and no
arguments.
It is a common confusion, because of the function's name, to use this when really you want just a normal if () {} else {}
construction instead.
Why does the ifelse function return only the first element of a vector provided as an argument?
From the help ?ifelse
:
"ifelse returns a value with the same shape as test which is filled
with elements selected from either yes or no depending on whether the
element of test is TRUE or FALSE."
I think this is to say that if your test is a vector of length one (like your TRUE) it returns a value of length one too. If the test has a length of two, it'll return a value of length two. (Recycling the elements of the designated value, if necessary.)
> ifelse(TRUE, c(2,3,4), "a")
[1] 2
> ifelse(c(TRUE,TRUE), c(2,3,4), "a")
[1] 2 3
> ifelse(c(FALSE,FALSE), c(2,3,4), "a")
[1] "a" "a"
How to return either a vector or string based on condition in ifelse statement?
You don't want to use ifelse
in this case because you need to return vectors of different length that your input. Just use a regular if/else
ggplot(data = data) +
aes(x = x , y = yy, color = if(ygroups > 1) get(group) else defaultcol) +
geom_point() +
labs(color="Color")
But you can't set selecific default colors in an aes(color=)
-- that will remap the color name via your color scale. If you just want to conditionally add the scale, then do
ggplot(data = data) +
aes(x = x , y = yy) +
{if( ygroups > 1) aes(color=.data[[group]])} +
geom_point()
(using .data[[ ]]
is recommended over using get()
)
Why does ifelse() return an integer value that is NOT a true or false argument r
You have factor
columns in the data. Your problem would be solved if you stringsAsFactors = FALSE
while constructing the dataframe.
df <- data.frame (a = c(rep("c",4), (rep(NA,4))),
b = c(rep(NA,4),rep("e",4)), stringsAsFactors = FALSE)
However, dplyr
has a nice coalesce
function which does exactly does what you need without using ifelse
.
library(dplyr)
df %>% mutate(ab = coalesce(a, b))
Using if/ifelse statement with vector conditions in R
You can also do a normal if statement, since it returns a value:
my_result = if(all(Vector1 == c(T,T,T))) {"Combo1"} else {"Combo2"}
The ifelse function is made for vectorized conditional statements.
By using the standard if statement, you remove potential ambiguity/misinterpretation because the standard if only evaluates one condition.
ifelse assignment does not return pre-defined character vector
ifelse
is the wrong tool here. You use ifelse
when you have a vector of logical tests and you wish to create a new vector of the same length. You have a single logical test, but want your output to be a vector.
What you are describing is better handled by an if
and else
clause:
states_abb <- if("Texas" %in% states) txnm_abb else canv_abb
states_abb
#> [1] "CA" "NV"
To try to get a feel for how ifelse
works, consider the following input and output:
condition <- c(TRUE, FALSE, FALSE)
input1 <- c("A", "b", "C")
input2 <- c("1", "2", "3")
result <- ifelse(condition, input1, input2)
result
#> [1] "A" "2" "3"
You will see that ifelse
is a vectorized, shorthand way of writing the following loop, which is a pattern that comes up surprisingly often in data wrangling:
result <- character(3)
for(i in 1:length(condition)) {
result[i] <- if(condition[i]) input1[i] else input2[i]
}
result
#> [1] "A" "2" "3"
Note though that this is not what you are trying to do in your own code.
Why ifelse function doesn't display vector as output in R
We may use if/else
here
if(s == 1) x else y
How does R handle NA in ifelse with 2 vectors?
In both the case add an additional check for NA
's since anything compared to NA
returns NA
.
ifelse(x == 1 & !is.na(x), 1, ifelse(y == 1 & !is.na(y), 2, 0))
#[1] 1 1 2 0 0
Related Topics
Order Discrete X Scale by Frequency/Value
Combine a List of Data Frames into One Data Frame by Row
Finding All Duplicate Rows, Including "Elements With Smaller Subscripts"
Subset Data Frame Based on Number of Rows Per Group
Interpreting "Condition Has Length ≫ 1" Warning from 'If' Function
Reorder Bars in Geom_Bar Ggplot2 by Value
In R, How to Get an Object'S Name After It Is Sent to a Function
Convert Continuous Numeric Values to Discrete Categories Defined by Intervals
Counting Unique/Distinct Values by Group in a Data Frame
How to Replace Na Values With Zeros in an R Dataframe
How to Trim Leading and Trailing White Space
Relative Frequencies/Proportions With Dplyr
Plot Two Graphs in Same Plot in R
Summarizing Multiple Columns With Dplyr
Side-By-Side Plots With Ggplot2
How to Force a Line Break in Rmarkdown'S Title
Position Geom_Text on Dodged Barplot
How to Find the Difference in Value in Every Two Consecutive Rows in R