Как вставить элементы в вектор?
У меня есть логический вектор, для которого я хочу вставить новые элементы в определенные индексы. Я придумал неуклюжие решения ниже, но есть ли более аккуратный способ?
probes <- rep(TRUE, 15)
ind <- c(5, 10)
probes.2 <- logical(length(probes)+length(ind))
probes.ind <- ind + 1:length(ind)
probes.original <- (1:length(probes.2))[-probes.ind]
probes.2[probes.ind] <- FALSE
probes.2[probes.original] <- probes
print(probes)
дает
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
и
print(probes.2)
дает
[1] TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
[13] TRUE TRUE TRUE TRUE TRUE
Так оно работает, но уродливо выглядит - любые предложения?
Ответы
Ответ 1
Вы можете сделать магию с индексами:
Сначала создайте вектор с выходными значениями:
probs <- rep(TRUE, 15)
ind <- c(5, 10)
val <- c( probs, rep(FALSE,length(ind)) )
# > val
# [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
# [13] TRUE TRUE TRUE FALSE FALSE
Теперь трюк. Каждый старый элемент получает ранг, каждый новый элемент получает половину ранга
id <- c( seq_along(probs), ind+0.5 )
# > id
# [1] 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0
# [16] 5.5 10.5
Затем используйте order
для сортировки в правильном порядке:
val[order(id)]
# [1] TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
# [13] TRUE TRUE TRUE TRUE TRUE
Ответ 2
Все это очень творческие подходы. Я думаю, что работать с индексами - это, безусловно, путь (решение Marek очень приятно).
Я бы просто упомянул, что есть функция, чтобы сделать примерно то: append()
.
probes <- rep(TRUE, 15)
probes <- append(probes, FALSE, after=5)
probes <- append(probes, FALSE, after=11)
Или вы можете сделать это рекурсивно с помощью своих индексов (вам нужно увеличить значение "после" на каждой итерации):
probes <- rep(TRUE, 15)
ind <- c(5, 10)
for(i in 0:(length(ind)-1))
probes <- append(probes, FALSE, after=(ind[i+1]+i))
Кстати, этот вопрос также был задан ранее в R-Help. Как говорит Барри:
"На самом деле я бы сказал, что не было никаких способов сделать это, так как я не думаю, что вы действительно можете вставить в вектор - вам нужно создать новый вектор, создающий иллюзию вставки!"
Ответ 3
Как насчет этого:
> probes <- rep(TRUE, 15)
> ind <- c(5, 10)
> probes.ind <- rep(NA, length(probes))
> probes.ind[ind] <- FALSE
> new.probes <- as.vector(rbind(probes, probes.ind))
> new.probes <- new.probes[!is.na(new.probes)]
> new.probes
[1] TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
[13] TRUE TRUE TRUE TRUE TRUE
Ответ 4
probes <- rep(TRUE, 1000000)
ind <- c(50:100)
val <- rep(FALSE,length(ind))
new.probes <- vector(mode="logical",length(probes)+length(val))
new.probes[-ind] <- probes
new.probes[ind] <- val
Некоторые тайминги:
Мой метод пользовательская система 0,03 0,00 0,03
Метод Марека пользовательская система 0,18 0,00 0,18
R добавить с циклом for пользовательская система 1,61 0,48 2,10
Ответ 5
Это сложно. Вот один из способов. Он выполняет итерацию по списку, вставляя каждый раз, поэтому он не слишком эффективен.
probes <- rep(TRUE, 15)
probes.ind <- ind + 0:(length(ind)-1)
for (i in probes.ind) {
probes <- c(probes[1:i], FALSE, probes[(i+1):length(probes)])
}
> probes
[1] TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
[13] TRUE TRUE TRUE TRUE TRUE
Это должно даже работать, если ind имеет повторяющиеся элементы, хотя ind необходимо сортировать для работы конструкции probes.ind.
Ответ 6
Или вы можете сделать это, используя функцию insertRow из пакета miscTools.
probes <- rep(TRUE, 15)
ind <- c(5,10)
for (i in ind){
probes <- as.vector(insertRow(as.matrix(probes), i, FALSE))
}