Reputation: 1656
Looking at this post, I thought ifelse
is vectorized in the sense that f(c(x1, x2, x3)) = c(f(x1), f(x2), f(x3))
.
So, I thought if the code for z1
(provided below) will perform the following for each element of the vector y
:
But, unfortunately it doesn't do that. It generates once for each case, and returns that very random number always.
Where exactly am I doing wrong? Or, is it actually the expected behaviour of ifelse
?
Just to note, if I use this as a wrapper function inside sapply
, I get the expected output z2
(in the sense that it is not deterministic as z1
where observing one occurrence of each case is enough), as you can see below.
y <- rbinom(n = 20,
size = 1,
prob = 0.5)
z1 <- ifelse(test = (y == 1),
yes = sample(x = c(1, 3, 5, 7, 9),
size = 1),
no = sample(x = c(0, 2, 4, 6, 8),
size = 1))
z2 <- sapply(X = y,
FUN = function(w)
{
ifelse(test = (w == 1),
yes = sample(x = c(1, 3, 5, 7, 9),
size = 1),
no = sample(x = c(0, 2, 4, 6, 8),
size = 1))
})
data.frame(y, z1, z2)
#> y z1 z2
#> 1 0 2 2
#> 2 1 1 3
#> 3 1 1 9
#> 4 1 1 7
#> 5 0 2 0
#> 6 0 2 2
#> 7 1 1 7
#> 8 1 1 7
#> 9 0 2 0
#> 10 1 1 5
#> 11 0 2 0
#> 12 0 2 0
#> 13 0 2 6
#> 14 0 2 0
#> 15 0 2 2
#> 16 1 1 7
#> 17 1 1 7
#> 18 0 2 2
#> 19 0 2 2
#> 20 0 2 0
unique(x = z1[y == 1])
#> [1] 1
unique(x = z1[y == 0])
#> [1] 2
Created on 2019-03-13 by the reprex package (v0.2.1)
Any help will be appreciated.
Upvotes: 2
Views: 904
Reputation: 145755
ifelse
isn't a function of one vector, it is a function of 3 vectors of the same length. The first vector, called test
, is a boolean, the second vector yes
and third vector no
give the elements in the result, chosen item-by-item based on the test
value.
A sample of size = 1
is a different size than test
(unless the length of test
is 1), so it will be recycled by ifelse
(see note below). Instead, draw samples of the same size as test
from the start:
ifelse(
test = (y == 1),
yes = sample(x = c(1, 3, 5, 7, 9), size = length(y), replace = TRUE),
no = sample(x = c(0, 2, 4, 6, 8), size = lenght(y), replace = TRUE)
)
The vectors don't actually have to be of the same length. The help page ?ifelse
explains: "If yes
or no
are too short, their elements are recycled." This is the behavior you observed with "It generates once for each case, and returns that very random number always.".
Upvotes: 6