Заменить повторяющиеся значения на 0 - PullRequest
3 голосов
/ 18 апреля 2019

Я хочу заменить повторяющиеся значения в моем фрейме данных на 0. Допускается некоторое количество повторений.

a<-c(1,2,3,4,4,4,5,5,5,5,5,9,9,150,220,220)

В случае, если допустимое количество повторений, скажем, 4. Ожидаемое решение должно выглядеть следующим образом:

a_new<-c(1,2,3,4,4,4,0,0,0,0,0,9,9,150,220,220)

Более 4 раз повторяющиеся значения заменяются на 0.

Использование функции

b<-rle(a)

Я могу определить количество повторений

Run Length Encoding
  lengths: int [1:8] 1 1 1 3 5 2 1 2
  values : num [1:8] 1 2 3 4 5 9 150 220

И заменить его на 0

b$values[b$lengths>4]<-0

Run Length Encoding
  lengths: int [1:8] 1 1 1 3 5 2 1 2
  values : num [1:8] 1 2 3 0 0 9 150 220

Вопрос состоит в том, как вставить повторения в этом случае 0 обратно в данные.

Ответы [ 5 ]

2 голосов
/ 18 апреля 2019

Вы можете использовать inverse.rle

a_new<-c(1,2,3,4,4,4,0,0,0,0,0,9,9,150,220,220)

b <- rle(a_new)

b$values[b$lengths>4]<-0

inverse.rle(b)

[1]   1   2   3   4   4   4   0   0   0   0   0   9   9 150 220 220
1 голос
/ 18 апреля 2019

С rleid

library(data.table)
data.table(a)[, a1 := if(.N >4) 0 else a, rleid(a)]$a1
#[1]   1   2   3   4   4   4   0   0   0   0   0   9   9 150 220 220
1 голос
/ 18 апреля 2019

Также возможна:

(a != rle(a)$values[rle(a)$lengths > 4]) * a

 [1]   1   2   3   4   4   4   0   0   0   0   0   9   9 150 220 220
1 голос
/ 18 апреля 2019

Другой способ через ave,

a[ave(a, a, FUN = length) > 4] <- 0
a
#[1]   1   2   3   4   4   4   0   0   0   0   0   9   9 150 220 220
1 голос
/ 18 апреля 2019

Вы также можете достичь этого в одной строке с

with(rle(a), rep(values * (lengths <= 4), lengths))
# [1]   1   2   3   4   4   4   0   0   0   0   0   9   9 150 220 220

, чтобы мы работали внутри rle(a) и непосредственно выполняли модификацию inverse.rle:

inverse.rle
# function (x, ...) 
# {
#     if (is.null(le <- x$lengths) || is.null(v <- x$values) || 
#         length(le) != length(v)) 
#         stop("invalid 'rle' structure")
#     rep.int(v, le) # The same except for le <= 4
# }
# <bytecode: 0x10470b4a8>
# <environment: namespace:base>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...