I am running a short if
function in R but am getting the following warning message:
In if ((runif(50, 0, 1) < 0.69)) { : the condition has length > 1 and only the first element will be used`.
My rudimentary grasp of R leads me to believe that runif
generates a vector but if
yields a single value, so I'm thinking this is the issue. Is there any simple substitution for if here?
Also i want the end product to be a matrix combination of the two arguments but i wasn't sure if it was correct to put 50 in the rnorm
function for both scenarios.
Test <-
if((runif(50, 0, 1)<0.69)) {
rnorm(50, 25, 4)
} else {
rnorm(50, 28, 4.3)
}
If statements tell R to run a line of code if a condition returns TRUE . An if statement is a good choice here because it allows us to control which statement is printed depending on which outcome occurs. Our if statement's condition should be an expression that evaluates to TRUE or FALSE .
The IF function is one of the most popular functions in Excel, and it allows you to make logical comparisons between a value and what you expect. So an IF statement can have two results. The first result is if your comparison is True, the second if your comparison is False.
A for loop executes a task for a defined number of elements, while an if statement tests a condition and then completes an action based on whether a result is true or false.
Syntax. If the Boolean expression evaluates to true, then the block of code inside the 'if' statement will be executed. If the Boolean expression evaluates to false, then the first set of code after the end of the 'if' statement (after the closing curly brace) will be executed.
if()
expects whetever is in the parentheses to evaluate to a logical vector of length 1 (TRUE
or FALSE
). If the vector is longer than 1, then as the warning says only the first element of the vector is used.
An alternative if ifelse()
where it is used as :
ifelse(test, TRUE_CASE, FALSE_CASE)
For your example we have:
set.seed(1)
ifelse(runif(50, 0, 1) < 0.69, rnorm(50, 25, 4), rnorm(50, 28, 4.3))
or
set.seed(1)
test <- runif(50, 0, 1)
Tcase <- rnorm(50, 25, 4)
Fcase <- rnorm(50, 28, 4.3)
ifelse(test, Tcase, Fcase)
Either is OK as ifelse()
generates the two vectors for TRUE_CASE
and FALSE_CASE
before doing the comparisons.
Example output is:
R> ifelse(test < 0.69, Tcase, Fcase)
[1] 24.77549 24.37682 19.11699 28.31967 26.67177 25.55472 27.41873 26.55069
[9] 24.78478 19.49176 23.34002 23.42284 24.76275 29.40010 29.14852 24.34191
[17] 33.19383 32.98973 27.22665 34.82338 30.40149 26.45833 28.07413 24.55062
[25] 28.52443 26.59242 22.55189 26.36448 28.67952 30.73209 32.92160 23.53111
[33] 20.82346 27.27888 35.23336 34.60647 26.01493 27.75896 25.20201 22.02691
[41] 26.31093 17.78017 26.79981 25.61301 33.69045 25.82438 22.16021 27.44291
[49] 27.22791 27.56918
Another way is to do this is to only generate the required values
want <- test < 0.69
res <- test ## copy vector of correct length
res[want] <- rnorm(S <- sum(want), 25, 4)
res[!want] <- rnorm(length(res) - S, 28, 4.3)
R> res
[1] 27.85067 24.70574 24.84946 22.04696 22.27336 36.03795 29.82793 23.70292
[9] 25.24064 22.64442 27.12598 18.92642 26.22623 18.85420 26.97382 23.79610
[17] 32.55148 31.81162 22.88688 25.33725 37.48624 22.39162 24.77241 17.34256
[25] 29.70633 18.34011 23.14588 20.53632 26.90338 21.99672 33.34867 25.06958
[33] 19.85480 18.43758 21.87467 26.80075 27.37908 24.92576 28.89241 23.72773
[41] 37.92431 21.28255 28.45495 19.05016 20.69923 29.96509 29.00012 22.51493
[49] 27.66824 26.56380
That obviously gives different numbers to the previous ones but only because we generated fewer random numbers. I doubt this will be any more efficient than ifelse()
for most problems.
You need any
or all
, which convert a vector of logicals into a single logical (well, actually a vector of length 1).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With