Здесь есть опция, использующая for
loop
a <- c("y","x","z","y","x","z")
b <- c(1,2,3)
. Хитрость заключается в том, чтобы сначала создать список, затем заменить все "x"
на b
и, наконец, вызвать unlist
.
a_list <- as.list(a)
for(i in which(a_list == "x")) {
a_list[[i]] <- b
}
Результат
unlist(a_list)
#[1] "y" "1" "2" "3" "z" "y" "1" "2" "3" "z"
Пожалуйста, примите во внимание ответ @ Shree!
Вот почему:
n <- 1e6
set.seed(1)
a <- sample(c("x", "y", "z"), size = n, replace = TRUE)
b <- 1:3
library(microbenchmark)
benchmark <- microbenchmark(
markus = markus(a, b),
IceCreamToucan = IceCreamToucan(a, b),
Shree = Shree(a, b)
)
autoplot(benchmark)
#Unit: milliseconds
# expr min lq mean median uq max neval
# markus 403.38464 467.03277 615.8078 556.74067 754.5117 1095.7035 100
#IceCreamToucan 401.34614 462.92680 602.1556 526.08280 687.8436 1422.0629 100
# Shree 52.33867 65.32323 157.6680 97.34066 162.0638 650.2571 100
функции
markus <- function(a, b) {
a_list <- as.list(a)
for(i in which(a_list == "x")) {
a_list[[i]] <- b
}
unlist(a_list)
}
Shree <- function(a, b) {
a <- rep(a, 1 + (length(b) - 1)*(a == "x"))
a[a == "x"] <- b
a
}
# from the comments
IceCreamToucan <- function(a, b) {
a_list <- as.list(a)
w <- which(a_list == "x")
a_list[w] <- rep(list(b), length(w)) # changed your answer slightly here
unlist(a_list)
}