2016-12-30 3 views
4

У меня есть векторы в R, содержащие много 0 и несколько ненулевых чисел. Каждый вектор начинается с ненулевого числа.Как заполнить значения в векторе?

< Например 1,0,0,0,0,0,2,0,0,0,0,0,4,0,0,0>

Я хотел бы установить все нули равны самому последнему ненулевому числу.

I.e. этот вектор станет < 1,1,1,1,1,1,2,2,2,2,2,2,4,4,4,4>

Мне нужно сделать это примерно за 100 векторов, содержащих около 6 миллионов записей. В настоящее время я использую цикл for:

for(k in 1:length(vector){ 

    if(vector[k] == 0){ 

    vector[k] <- vector[k-1] 
    } 
} 

Есть ли более эффективный способ сделать это?

Спасибо!

+0

вектора последовательным кроме нулей? Если это так, я думаю, вы сможете использовать 'cummax'. то есть: 'vector <- cummax (vector)' – rosscova

+0

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

+1

Если вы наведите указатель на стрелку вверх, в нем говорится: «Этот комментарий добавляет что-то полезное для сообщения». Я думаю, что это именно то, что это значит. Возможно, не полный ответ, но добавляет что-то полезное. – G5W

ответ

7

Один из вариантов, было бы заменить те 0 с NA, а затем использовать zoo::na.locf:

x <- c(1,0,0,0,0,0,2,0,0,0,0,0,4,0,0,0) 
x[x == 0] <- NA 
zoo::na.locf(x) ## you possibly need: `install.packages("zoo")` 
# [1] 1 1 1 1 1 1 2 2 2 2 2 2 4 4 4 4 

Благодаря Ричард показал мне, как использовать replace,

zoo::na.locf(replace(x, x == 0, NA)) 
4

Вы можете попробовать это:

k <- c(1,0,0,0,0,0,2,0,0,0,0,0,4,0,0,0) 
k[which(k != 0)[cumsum(k != 0)]] 

или другой случай, когда cummax не было бы целесообразно

k <- c(1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0) 
k[which(k != 0)[cumsum(k != 0)]] 

Логика:

  • я держу "след" из индексов векторных элементов, которые не равны нулю which(k != 0), позволяет обозначить этот новый вектор как x, x=c(1, 7, 13)

  • Далее Я собираюсь «пробовать» этот новый вектор. Как? От k Я создаю новый вектор, который увеличивает каждый раз, когда существует ненулевая элемент cumsum(k != 0), позволяет обозначить этот новый вектор как yy=c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3)

  • Я «выборка» из вектора x: x[y] т.е. принимая первый элемент x 6 раз, затем второй элемент 6 раз и третий элемент 3 раза. Обозначим этот новый вектор в z, z=c(1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 13, 13, 13)

  • Я «отбора проб» из вектора k, k[z], т.е. я беру первый элемент в 6 раз, а затем 7-й элемент 6 раз тогда 13-й элемент 3 раза.

+1

Это действительно умно, но функциональность немного непрозрачна, по крайней мере для меня (мне пришлось разделить ее и на самом деле запустить ее шаг за шагом, чтобы понять ее). Я думаю, было бы здорово, если бы вы могли добавить краткое объяснение того, что происходит? – rosscova

1

Добавить в @ 李哲源 ответ:

Если требуется заменить ведущий Nas с ближайшим не-NA значением, и заменить другую Nas с последним не-NA значением, коды могут быть:

x <- c(0,0,1,0,0,0,0,0,2,0,0,0,0,0,4,0,0,0) 
zoo::na.locf(zoo::na.locf(replace(x, x == 0, NA),na.rm=FALSE),fromLast=TRUE) 
# you possibly need: `install.packages("zoo")` 
# [1] 1 1 1 1 1 1 1 1 2 2 2 2 2 2 4 4 4 4 
Смежные вопросы