'Conditional assignment of vector in R
I'd like to assign a vecotr based on a conditional statement. How do I do this? This is what I have tried:
zero_rows <- ifelse(i == 1, c(2,3,4,7,12),
ifelse(i == 2, c(4,7,12),
ifelse(i == 3, c(2,3,4,7,9,12),
ifelse(i == 4, c(4,7,9),
ifelse(i == 5, c(4,12),
ifelse(i == 6, c(9,12),
ifelse(i == 7, 12,
ifelse(i == 8, c(2,3,4,7,9,12), 0))))))))
and
zero_rows <- case_when(i == 1 ~ c(2,3,4,7,12),
i == 2 ~ c(4,7,12),
i == 3 ~ c(2,3,4,7,9,12),
i == 4 ~ c(4,7,9),
i == 5 ~ c(4,12),
i == 6 ~ c(9,12),
i == 7 ~ 12,
i == 8 ~ c(2,3,4,7,9,12),
TRUE ~ 0)
Solution 1:[1]
It may be a case for switch
fn <- function(i) {
i <- as.character(i)
switch(i,
"1" = c(2,3,4,7,12),
"2" = c(4,7,12),
"3" = c(2,3,4,7,9,12),
"4" = c(4,7,9),
"5" = c(4,12),
"6" = c(9,12),
"7" = 12,
"8" = c(2,3,4,7,9,12),
0)
}
-testing
> fn(1)
[1] 2 3 4 7 12
> fn(2)
[1] 4 7 12
> fn(3)
[1] 2 3 4 7 9 12
> fn(9)
[1] 0
> fn(10)
[1] 0
If we want to do this on each value of a column ('col1'), use rowwise and wrap the output in a list
library(dplyr)
df1 %>%
rowwise %>%
mutate(out = list(fn(col1)))
Or with map
library(purrr)
df1 %>%
mutate(out = map(col1, fn))
ifelse/if_else/case_when - expects all the arguments to be of same length. Based on the code showed, it is not the case where the length differ based on the input arguments
Solution 2:[2]
We can try nested ifelse along with list like below
f <- function(i) {
ifelse(i == 1, list(c(2, 3, 4, 7, 12)),
ifelse(i == 2, list(c(4, 7, 12)),
ifelse(i == 3, list(c(2, 3, 4, 7, 9, 12)),
ifelse(i == 4, list(c(4, 7, 9)),
ifelse(i == 5, list(c(4, 12)),
ifelse(i == 6, list(c(9, 12)),
ifelse(i == 7, list(12),
ifelse(i == 8, list(c(2, 3, 4, 7, 9, 12)), 0)
)
)
)
)
)
)
)[[1]]
}
Solution 3:[3]
It would be most natural to use i as an index, like so:
l <- list(c(2, 3, 4, 7, 12),
c(4, 7, 12),
c(2, 3, 4, 7, 9, 12),
c(4, 7, 9),
c(4, 12),
c(9, 12),
12,
c(2, 3, 4, 7, 9, 12))
zero_rows <- ifelse(i %in% seq_along(l), l[i], list(0))
Though it would be safer and faster to avoid ifelse altogether:
ok <- i %in% seq_along(l)
zero_rows <- rep.int(list(0), length(i))
zero_rows[ok] <- l[i[ok]]
The first approach assumes that the elements of i are all greater than or equal to 1. The second approach supports any numeric i.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | ThomasIsCoding |
| Solution 3 |
