Using the IF Function in R

I run a short if function in R, but I get 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 understanding of R makes me think that runif generates a vector, but if gives a single value, so I think this is a problem. Is there a simple wildcard if here?

I also want the final product to be a matrix combination of two arguments, but I was not sure if it was right to put 50 in the rnorm functions for both scenarios.

 Test <- if((runif(50, 0, 1)<0.69)) { rnorm(50, 25, 4) } else { rnorm(50, 28, 4.3) } 
+4
source share
2 answers

if() expects whetever to be in parentheses to compute a logical vector of length 1 ( TRUE or FALSE ). If the vector is longer than 1, then, as warns, only the first element of the vector is used.

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 normal, as ifelse() generates two vectors for TRUE_CASE and FALSE_CASE before doing comparisons.

Output Example:

 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 create only the necessary 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 

This, obviously, gives different numbers to the previous ones, but only because we generated fewer random numbers. I doubt it will be more efficient than ifelse() for most problems.

+7
source

You need any or all that convert the vector of logical elements into one logical (well, actually a vector of length 1).

+1
source

All Articles