Reputation: 144
This seems like a simple question, but I have not been able to successfully google it. I have two vectors of strings that I would like to combine based on a 3rd vector of TRUE FALSE
.
Example:
strvec1 <- c("str1", "str2", "str3")
strvec2 <- c("alt1", "alt2", "alt3")
boolvec <- c(FALSE, FALSE, TRUE)
I would like for to call somefunction(strvec1, strvec2, boolvec)
and for the result to be c("str1", "str2", "alt3")
.
Thank you for the help.
Upvotes: 2
Views: 55
Reputation: 70256
If the strvectors are the same length, you can do:
cbind(strvec1, strvec2)[cbind(seq_along(strvec1), boolvec+1)]
# [1] "str1" "str2" "alt3"
And in a function:
f <- function(x,y,z) cbind(x, y)[cbind(seq_along(x), z+1L)]
f(strvec1, strvec2, boolvec)
# [1] "str1" "str2" "alt3"
Another option would be replace
:
f2 <- function(x, y, z) replace(x, which(z), y[z])
f2(strvec1, strvec2, boolvec)
# [1] "str1" "str2" "alt3"
Here's a little comparison - only as rough indication:
strvec1 <- sample(letters, 1e6, T)
strvec2 <- sample(letters, 1e6, T)
boolvec <- sample(c(TRUE, FALSE), 1e6, T)
somefunction <- function(x, y, z) ifelse(z, y, x)
f <- function(x,y,z) cbind(x, y)[cbind(seq_along(x), z+1L)]
system.time(somefunction(strvec1, strvec2, boolvec))
# User System elapsed
# 0.494 0.025 0.519
system.time(f(strvec1, strvec2, boolvec))
# User System elapsed
# 0.048 0.008 0.056
system.time(f2(strvec1, strvec2, boolvec))
# User System elapsed
# 0.048 0.002 0.050
Upvotes: 1
Reputation: 2396
The somefunction
you want is ifelse
:
strvec1 <- c("str1", "str2", "str3")
strvec2 <- c("alt1", "alt2", "alt3")
boolvec <- c(FALSE, FALSE, TRUE)
ifelse(boolvec, strvec2, strvec1)
# [1] "str1" "str2" "alt3"
NB: Note the order of strvec1
and strvec2
. TRUE
maps to the second (if
) argument and FALSE
maps to the third (else
) argument.
Upvotes: 1
Reputation: 92282
Another option would be just
somefunction <- function(x, y, z) ifelse(z, y, x)
somefunction(strvec1, strvec2, boolvec)
## [1] "str1" "str2" "alt3"
Upvotes: 2