2013-05-30 1 views
3

Учитывая вектор, такой какR функция респ с перезаписать элементами

> x 
[1] 1 1 2 1 1 1 5 1 1 1 5 7 1 1 1 1 1 1 1 1 1 

Я хочу повторить элементы п раз --BUT-- Я хочу, чтобы старые элементы, которые будут перезаписаны репликаций. Используя основные функции респ дает:

> rep(x,x) 
[1] 1 1 2 2 1 1 1 5 5 5 5 5 1 1 1 5 5 5 5 5 7 7 7 7 7 7 7 1 1 1 1 1 1 1 1 1 

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

112111511157111111111 
112211511157111111111 
112211555557111111111 
112211555555555111111 
112211555557777777111 

Обратите внимание, для каждого N-реплицируемого элемента он просто перезаписывает N соседних правых соседей. Я мог бы сделать это в цикле, но есть ли быстрый векторный подход для этого?

na.locf близок (предварительно устанавливает 1s в NA), но (как я понимаю) он заполнит ВСЕ или фиксированное число только самых правых NA с значением rep, а не точно N правыми соседями.

Возможной альтернативой может быть наличие всех нулей вместо исходных и только повторение и перезапись элементов N раз с двоичными значениями. , например. выше будет ... например:

x<- c(0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0) 
sig<-c(0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0) 

редактировать: для уточнения, оно должно компактно распространяться на любое количество повторяемых элементов (те же функции, как репы).

+1

для первой задачи, некоторые умные комбинации 'embed',' inverse.rle' и индексирование, возможно, но не сегодня для меня. – baptiste

+0

Я даже не знал, что могу инвертировать rle. Спасибо за указатель. – pat

+0

x длина 21 ваш ответ длина 22. если это «001100111111111111000», длина 21? – user1609452

ответ

0
x <- c(0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0) 

dumFun <- function(a,b,c){rep(c(0,1,0), times = c(a-1,b,max(c-b-a+1,0)))} 
1*Reduce('|', 
     mapply(dumFun, a = seq_along(x), b = x, c =length(x), SIMPLIFY= FALSE)) 

[1] 0 0 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 

В результате получается список векторов нулей, заполненных 1 символом х. Затем он последовательно применяет операцию ИЛИ к каждому элементу списка.

Мы можем обернуть это в функции:

getSignal <- function(x){ 
    dumFun <- function(a,b,c){ 
        rep(c(0,1,0), times = c(a,b,max(c-b-a,0))) 
        } 
    1*Reduce('|', 
     mapply(dumFun, a = seq_along(x)-1, b = x, c =length(x), 
                 SIMPLIFY= FALSE)) 
} 

мы можем применить подобную идею, чтобы справиться с первой проблемой:

getRep <- function(x){ 
    dumFun <- function(a,b,c){ 
        rep(c(0,b,0), times = c(a,b,max(c-b-a,0))) 
      } 
    Reduce('pmax', 
     mapply(dumFun, a = seq_along(x)-1, b = x, c =length(x), 
                 SIMPLIFY= FALSE)) 
} 

y <- c(1, 1, 2, 1, 1, 1, 5, 1, 1, 1, 5, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1) 
getRep(y) 
[1] 1 1 2 2 1 1 5 5 5 5 5 7 7 7 7 7 7 7 1 1 1 
1
y <- x 
for (i in unique(y)) {    # or perhaps sort(unique(y)) 
    for (j in which(y==i)) { 
     x[seq(j, length.out=i)] <- i 
    } 
} 

x 
## [1] 1 1 2 2 1 1 5 5 5 5 5 7 7 7 7 7 7 7 1 1 1