2015-08-11 2 views
0

Мне нужны некоторые подсказки, чтобы создать эффективный цикл в векторе, но для цикла «FOR ...» из-за проблем с оптимизацией. На первый взгляд рекомендуется использовать такие функции, как apply(), sapply().Как закодировать вектор, сравнивающий строки без FOR

У меня есть вектор преобразуется в матрицу:

x1<-c(1,2,4,1,4,3,5,3,1,0) 

шлейфового вектора мне нужно заменить все x1 [+ 1] = x1 [I], если х [г]> х [I + 1 ]. Пример: Входной вектор:

x1<-as.matrix(c(1,2,4,1,4,3,5,3,1,0)) 

Выходной вектор:

c(1,2,4,4,4,4,5,5,5,5) 

Мой подход заключается в использовании функции пользователя в apply(), но у меня есть некоторые трудности, как правильно закодировать отношение х [I] и x [i + 1] в пользовательской функции. Буду очень признателен за ваши идеи или советы.

+5

только 'cummax (x1)'? – Khashaa

+0

@Khashaa Пожалуйста, подумайте, что это решение. Это отличный вариант. – akrun

+0

@akrun Слишком короткий для правильного ответа. Вы могли бы также добавить это к своему ответу. – Khashaa

ответ

2

В общем, вы можете использовать Reduce с accumulate=TRUE для кумулятивных операций

Reduce(max,x1,accumulate=TRUE) 
# [1] 1 2 4 4 4 4 5 5 5 5 

Но @Khashaa указывает, общие случаи cumsum, cumprod, cummin, и ваш, cummax предоставляются в качестве эффективной базы функции.

cummax(x1) 
# [1] 1 2 4 4 4 4 5 5 5 5 
+0

Спасибо A. Webb. cummax (x1) действительно замечательный. лучший результат всех вариантов - прошедшее время составляет 0,02 секунды на вектор из 1mio пунктов :-) –

2

Мы могли бы сделать это, используя ave. (Использование vector x1)

ave(x1,cumsum(c(TRUE,x1[-1]>x1[-length(x1)])), FUN=function(x) head(x,1)) 
#[1] 1 2 4 4 4 4 5 5 5 5 

Мы создаем переменную группировку на основе состояния, описанном в посте ФПА в. Проверьте, является ли последующий элемент (x1[-1] - удаленным первым элементом) больше текущего элемента (x1[-length(x1)] - удалены последний элемент).

x1[-1]>x1[-length(x1)] 
#[1] TRUE TRUE FALSE TRUE FALSE TRUE FALSE FALSE FALSE 

Длина на единицу меньше длины вектора x1. Таким образом, мы добавляем TRUE сделать длину, равную, а затем сделать cumsum

cumsum(c(TRUE,x1[-1]>x1[-length(x1)])) 
#[1] 1 2 3 3 4 4 5 5 5 5 

Это мы используем в качестве группировки переменной в ave и выберите первое наблюдение «x1» внутри каждой группы


Другой вариант должен был бы получить логический индекс (c(TRUE, x1[-1] > x1[-length(x1)])) по-прежнему, отрицать его (!), чтобы TRUE становился FALSE, а FALSE как TRUE, преобразовывал значения TRUE в 'NA' (NA^(!...)), а затем использовал na.locf от library(zoo), чтобы заменить значения NA с предыдущим значением, отличным от NA.

library(zoo) 
na.locf(x1*NA^(!c(TRUE,x1[-1]>x1[-length(x1)]))) 
#[1] 1 2 4 4 4 4 5 5 5 5 
+1

Ваши подсказки действительно замечательные! –

+0

@DimonD. Рад знать, что это помогло. Спасибо за ответ. – akrun

Смежные вопросы