The Art of R Programming

(WallPaper) #1
What actually happens in that nestedifelse()? Let’s take a careful look.
First, for the sake of concreteness, let’s find what the formal argument names
are in the functionifelse():

> args(ifelse)
function (test, yes, no)
NULL

Remember, for each element oftestthat is true, the function evaluates to
the corresponding element inyes. Similarly, iftest[i]is false, the function
evaluates tono[i]. All values so generated are returned together in a vector.
In our case here, R will execute the outerifelse()call first, in whichtest
isg=="M", andyesis 1 (recycled);nowill (later) be the result of executing
ifelse(g=="F",2,3). Now sincetest[1]is true, we generateyes[1], which is 1.
So, the first element of the return value of our outer call will be 1.
Next R will evaluatetest[2]. That is false, so R needs to findno[2].
R now needs to execute the innerifelse()call. It hasn’t done so before,
because it hasn’t needed it until now. R uses the principle oflazy evalu-
ation, meaning that an expression is not computed until it is needed.
R will now evaluateifelse(g=="F",2,3), yielding (3,2,2,3,3,3,2); this isno
for the outerifelse()call, so the latter’s second return element will be the
second element of (3,2,2,3,3,3,2), which is 2.
When the outerifelse()call gets totest[4], it will see that value to be
false and thus will returnno[4]. Since R had already computedno, it has the
value needed, which is 3.
Remember that the vectors involved could be columns in matrices, which
is a very common scenario. Say our abalone data is stored in the matrixab,
with gender in the first column. Then if we wish to recode as in the preced-
ing example, we could do it this way:

> ab[,1] <- ifelse(ab[,1] == "M",1,ifelse(ab[,1] == "F",2,3))

Suppose we wish to form subgroups according to gender. We could use
which()to find the element numbers corresponding to M, F, and I:

> m <- which(g == "M")
> f <- which(g == "F")
> i <- which(g == "I")
>m
[1]156
>f
[1]237
>i
[1] 4

52 Chapter 2

Free download pdf