2012-06-28 2 views
1

Я хотел бы преобразовать эту логику с чисто матричными операциями, а не для циклов. Логика заключается в том, что в моем двоичном векторе значений я хочу отметить каждую точку перехода (т. Е. Где 0 превращается в 1 и где 1 превращается в 0). В противном случае я хочу сохранить исходные значения. В то время как простой цикл достаточно быстр для небольшого вектора, мне нужно будет выполнить эту операцию несколько раз над большими наборами данных, следовательно, необходимость в эффективности с помощью макетов.R - логическое манипулирование с помощью векторных операций

x <- c(1,0,0,0,0,1,1,0,0,1,0,1,0,1,0,0,0,1); 
y <- rep(-2, length(x)); 
y[1] <- x[1]; 
for(i in 2:length(x)){ 
    if((x[i]==1 && x[i-1]==0) || (x[i]==0 && x[i-1]==1)){ 
     y[i] = -1; 
    } 
    else{ 
     y[i] = x[i]; 
    } 
} 

Окончательное значение у 1 -1 0 0 0 -1 1 -1 0 -1 -1 -1 -1 -1 -1 0 0 -1

Я новый преобразовать в R, многие заранее спасибо

ответ

3

Вы можете использовать rle для этого:

x.rle <- rle(x)$lengths 

x[cumsum(x.rle[1:(length(x.rle) - 1)]) + 1] <- -1 


> x 
[1] 1 -1 0 0 0 -1 1 -1 0 -1 -1 -1 -1 -1 -1 0 0 -1 
+0

Спасибо, что это работает !!! Я даже не знал, что существует rle :) – user1480926

1

Вот еще один из возможных решений:

x2 <- c(x[1], x[1:(length(x) - 1)]) 

x_out <- x 
x_out[x != x2] <- -1 
x_out 
[1] 1 -1 0 0 0 -1 1 -1 0 -1 -1 -1 -1 -1 -1 0 0 -1 
+0

Спасибо вам, что вы. Это тоже довольно элегантно и не требует понимания кодировки длины пробега и т. Д. – user1480926

+0

Позор Я не могу принять оба решения :) – user1480926

+0

Добро пожаловать. Надеюсь, это полезно для вас, или для кого-то еще! – bdemarest

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