Замените последовательность одинаковых значений длины › 2

У меня есть датчик, который измеряет переменную, и когда нет связи, он всегда возвращает последнее увиденное значение вместо NA. Поэтому в моем векторе я хотел бы заменить эти идентичные значения импутированным значением (например, na.approx).

set.seed(3)
vec <- round(runif(20)*10)
####  [1] 2 8 4 3 6 6 1 3 6 6 5 5 5 6 9 8 1 7 9 3

Но мне нужны только последовательности больше 2 (3 или более одинаковых чисел), потому что 2 одинаковых числа могут появиться естественным образом. (в предыдущем примере последовательность тегов будет 5 5 5)

Я попытался сделать это с помощью diff, чтобы пометить свои идентичные точки (c(0, diff(vec) == 0)), но я не знаю, как справиться с условием length == 2...

ИЗМЕНИТЬ мой ожидаемый результат может быть таким:

####  [1] 2 8 4 3 6 6 1 3 6 6 5 NA NA 6 9 8 1 7 9 3

(Второе идентичное значение последовательности из 3 или более, скорее всего, тоже неверное значение)

Спасибо


person agenis    schedule 15.06.2017    source источник


Ответы (2)


вы можете использовать rle для получения индексов позиций, где должно быть назначено NA.

vec[with(data = rle(vec),
     expr = unlist(sapply(which(lengths > 2), function(i)
         (sum(lengths[1:i]) - (lengths[i] - 2)):sum(lengths[1:i]))))] = NA
vec
#[1]  2  8  4  3  6  6  1  3  6  6  5 NA NA  6  9  8  1  7  9  3

В функции

foo = function(X, length){
   replace(x = X,
           list = with(data = rle(X),
                       expr = unlist(sapply(which(lengths > length), function(i)
                           (sum(lengths[1:i]) - (lengths[i] - length)):sum(lengths[1:i])))),
           values = NA)
}
foo(X = vec, length = 2)
#[1]  2  8  4  3  6  6  1  3  6  6  5 NA NA  6  9  8  1  7  9  3
person d.b    schedule 15.06.2017

вы можете использовать функцию lag

set.seed(3)
> vec <- round(runif(20)*10)
> 
> vec
 [1] 2 8 4 3 6 6 1 3 6 6 5 5 5 6 9 8 1 7 9 3
> 
> vec[vec == lag(vec) & vec == lag(vec,2)] <- NA
> 
> vec
 [1]  2  8  4  3  6  6  1  3  6  6  5  5 NA  6  9  8  1  7  9  3
> 
person Mouad_Seridi    schedule 15.06.2017
comment
Круто. Можно ли также заменить NA, начиная со второй 5, а не с третьей? (я обновил свой ожидаемый результат) - person agenis; 15.06.2017
comment
да, это будет дополнительный шаг vec[which(is.na(vec)) - 1] <- NA - person Mouad_Seridi; 15.06.2017
comment
хорошо, я мог бы пойти с этим, хотя это испортило бы естественные NA... изначально присутствующие в векторе (это может случиться). Я должен был бы вменить их в первую очередь. - person agenis; 15.06.2017
comment
вы можете обойти это, назначив 3-м определенное значение, например -999, затем сделайте то же самое для 2-го, и как только вы закончите, назначьте всем им NA, дайте мне знать, если вам нужна помощь с этим. - person Mouad_Seridi; 15.06.2017