© Margot Tollefson 2019
Margot TollefsonR Quick Syntax Referencehttps://doi.org/10.1007/978-1-4842-4405-0_14

14. The Functions ifelse() and switch()

Margot Tollefson1 
(1)
Stratford, IA, USA
 

The two functions ifelse() and switch() execute flow control within a function or script. The function ifelse() evaluates a logical expression and chooses one of two values based on the result. The function switch() takes a value as an argument and returns another value based on the value of the first argument.

The Function ifelse( )

The ifelse() function takes three arguments. The first is a logical object or any object that can be coerced to logical, such as objects of the atomic modes or objects of mode list where there is only one level of depth to the list and where each element takes on only one value. Also, you can use a function that returns values that can be coerced to logical. The second argument is the value(s) to be returned where the first argument is true. The third argument is the value(s) to be returned where the first argument is false.

Each element of the first argument is tested separately. Elements of mode character and missing elements return NA. Otherwise, the value that is returned for a given element is the value in the same position in the second (or third) argument. For example, if the first argument is the vector (T,T,F,T), the second argument is the vector (1,2,1,2), and the third argument is (4,5,6,4), then ifelse() returns (1,2,6,2). That is:
> ifelse( c( T, T, F, T ), c( 1, 2, 1, 2 ), c( 4, 5, 6, 4 ) )
[1] 1 2 6 2
If possible, the result has the same dimensions as the first argument. Otherwise, a vector of mode list of length equal to the length of the first argument is returned. For example:
> a.mat = matrix( 0:3, 2, 2 )
> a.mat
     [,1] [,2]
[1,]    0    2
[2,]    1    3
> a.list = list( a.mat, c( "a", "b", "c" ) )
> a.list
[[1]]
     [,1] [,2]
[1,]    0    2
[2,]    1    3
[[2]]
[1] "a" "b" "c"
> ifelse( a.mat, 1:4, 30:33 )
     [,1] [,2]
[1,]   30    3
[2,]    2    4
> ifelse( a.mat, 1:4, a.list )
[[1]]
     [,1] [,2]
[1,]    0    2
[2,]    1    3
[[2]]
[1] 2
[[3]]
[1] 3
[[4]]
[1] 4

Note that in the second call to ifelse(), the first element of a.mat results in a FALSE and the first element of a.list is a matrix, so a list is generated.

If the first argument is of length less than the length of the second (or third) argument, only those elements in the second (or third) argument up to the length of the first argument will be used. For example:
> ifelse( c( T, F ), 1:5, 10:15 )
[1]  1 11

The first element of 1:5 is 1 and the second element of 10:15 is 11, so (1,11) is returned.

If the first argument is of length longer than the second (or third) argument, the second (or third) argument cycles. For example:
> ifelse( c( T, F, F, F, T ), 1:3, 10:12 )
[1]  1 11 12 10  2

The second argument cycles to (1,2,3,1,2) and the third argument cycles to (10,11,12,10,11).

If the modes of the resulting elements are not the same, then the result will have the mode of the element with the highest hierarchy, where the hierarchy goes—from lowest to highest—logical, integer, double, complex, character, and list. Objects of mode NULL and raw give an error. For example:
> ifelse( c( T, F, F, F, T ), 1:5+1i, 1:5 )
[1] 1+1i 2+0i 3+0i 4+0i 5+1i
> ifelse( c( T, F, F, F, T ), as.raw( 2:6 ), as.raw( 12:16 ) )
Error in ifelse(c(T, F, F, F, T), as.raw(2:6), as.raw(12:16)) :
  incompatible types (from raw to logical) in subassignment type fix
A function can be used as the value for any of the three arguments. If the function(s) is evaluated, the result(s) of the function is(are) returned first. The last result is the result of the substitution. For example:
> f.fun = function( mu, se=1, alpha=.05 ){
  q_value = qnorm( 1-alpha/2, mu, se )
  print( q_value )
}
> ifelse( f.fun( 1:2, alpha=1.0 ), f.fun( 1:2 ), f.fun( 3 ) )
[1] 1 2
[1] 2.959964 3.959964
[1] 2.959964 3.959964
> ifelse( f.fun( 0:2, alpha=1.0 ), f.fun( 1:2 ), f.fun( 3 ) )
[1] 0 1 2
[1] 2.959964 3.959964
[1] 4.959964
[1] 4.959964 3.959964 2.959964

Note that in the first call to f.fun(), alpha is set to 1.0, so the median is returned. Also, in the first call, the first two functions are evaluated, while in the second call all three functions are evaluated.

If the result is assigned to an object, then the results of the functions are printed at the console, but the result of the ifelse() is passed to the object. For example:
> a=ifelse ( f.fun( 1:2, alpha=1.0 ), f.fun( 1:2 ), f.fun( 3 ) )
[1] 1 2
[1] 2.959964 3.959964
> a
[1] 2.959964 3.959964
The function ifelse() can be nested. For example, a first-order Markov chain of length six with two states, where the transition matrix is
$$ left[egin{array}{cc}0.7& 0.3\ {}0.8& 0.2end{array}
ight] $$
can be generated using nested ifelse() functions. That is, letting “A” be the first state and “B” be the second state:
> set.seed( 6978 )
> mc="A"
> for ( i in 2:6 ) {
+   rn = runif( 1 )
+   mc = c( mc, ifelse( mc[i-1]=="A", ifelse( rn<=0.7, "A", "B" ),
+.              ifelse( rn<=0.8, "B", "A" ) ) )
+ }
> mc
[1] "A" "A" "B" "B" "B" "B"

You can find more information about ifelse()by entering ?ifelse at the R prompt or by using the Help tab in R Studio.

The Function switch( )

The function switch() takes any number of arguments. The first argument tells switch() which of the following arguments to return. The arguments that follow the first argument are the objects to be returned. The first argument must be numeric, logical, complex, character, or NA, and it must consist of a single element. The rest of the arguments can be of any mode and dimension. Commas separate the arguments.

If the first argument is numeric, the number is rounded down to an integer; if logical, TRUE is coerced to 1 and FALSE to 0; and if complex, the imaginary part is discarded and the real part is treated like numeric. A warning is given.

The function returns the argument indicated by the first argument. For example, if the first argument is 3, then the fourth argument is returned. That is:
> switch( 3, 5, "a", "b", 6 )
[1] "b"
If the first argument is larger than the number of arguments minus one, is less than one, or is NA, then a NULL object is returned. For example:
> switch( 0, 1, 2, 3 )
> mode( switch( 0, 1, 2, 3 ) )
[1] "NULL"

A character string for the first element causes switch() to behave differently. The function looks at the names of the arguments following the character string to try to find a match. All of the following arguments must be named with the exception of one possible element without a name. (Arguments can be named in the listing by entering the name, followed by an equal sign, followed by an—optional—value.)

If there is an argument without a name, then that argument becomes the default value if there is no match to the character string. If there is no argument without a name, then the default value is a NULL object. For example:
> switch( "e", a=1, b=2, c=3, d=4, e=f.fun( 0 ) )
[1] 1.959964
> switch( "e", a=1, b=2, c=3, d=4, 25 )
[1] 25
> switch( "e", a=1, b=2, c=3, d=4 )
> mode( switch( "e", a=1, b=2, c=3, d=4 ) )
[1] "NULL"

The unnamed argument can appear anywhere in the listing except as the first argument. If more than one unnamed argument is entered, then switch() returns an error.

With a character string for the first argument, the subsequent arguments do not have to be assigned a value, only a name. If the character string matches a name without a value, then switch() continues along the listing of the arguments and returns the value of the next argument with a value. If none of the subsequent arguments contain a value, switch returns a NULL object. For example:
> switch( "b", a=1, b=, c=3, d= )
[1] 3
> switch( "b", a=1, b=, c=, d= )
> mode( switch( "b", a=1, b=, c=, d= ) )
[1] "NULL"

Note that the first argument is enclosed in quotes, while the names of the subsequent arguments are not. The switch() function can be nested.

You can find more information about switch() by entering ?switch at the R prompt or by using the Help tab in R Studio.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.206.171