Подтвердить что ты не робот

Как вставить элементы в вектор?

У меня есть логический вектор, для которого я хочу вставить новые элементы в определенные индексы. Я придумал неуклюжие решения ниже, но есть ли более аккуратный способ?

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

Так оно работает, но уродливо выглядит - любые предложения?

4b9b3361

Ответ 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))
}