2010-08-16 5 views
1

У меня есть первый вектор, скажем x, который состоит только из 1 и -1. Тогда у меня есть второй вектор y, состоящий из 1, -1 и нулей. Теперь я хотел бы создать вектор г, содержащий в индексе 1, если IA x[i] равен 1 и 1 существует в пределах вектора у между п прецедентных элементов (y[(i-n):i]) ...Создание определенного вектора без цикла или рекурсии в R

более формально: z <- ifelse(x == 1 && 1 %in% y[(index(y)-n):index(y)],1,0)

Я хочу создать такой вектор в R без цикла или рекурсии. Вышеприведенное предложение не работает, поскольку оно не распознает элемент y[(index(y)-n):index(y)].

Большое спасибо за вашу поддержку

ответ

1

Вы можете использовать apply, как это, хотя это, по сути довольно способ сделать петлю, я не уверен, если это будет быстрее (это может или не может) ,

y1 <- unlist(lapply(1:length(x), function(i){1 %in% y[max(0, (i-n)):i]})) 
z <- as.numeric(x==1) * as.numeric(y1) 
+0

Привет Нико, Большое спасибо за быстрый и очень полезный комментарий, я буду проверять скорость, но я довольно уверен, что ваше решение быстрее, чем обычный цикл в R. сердечным приветом , martin – martin

2

Вот такой подход, который использует функцию cumsum для проверки числа тех, которые были замечены до сих пор. Если число единиц в позиции i больше числа единиц в позиции i-n, то условие справа будет выполнено.

## Generate some random y's. 
> y <- sample(-1:1, 25, replace=T) 
> y 
[1] 0 1 -1 -1 -1 -1 -1 1 -1 -1 -1 -1 0 0 -1 -1 -1 1 -1 1 1 0 0 0 1 
> n <- 3 
## Compute number of ones seen at each position. 
> cs <- cumsum(ifelse(y == 1, 1, 0)) 
> lagged.cs <- c(rep(0, n), cs[1:(length(cs)-n)]) 
> (cs - lagged.cs) > 0 
[1] FALSE TRUE TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE 
[13] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE 
[25] TRUE 
+0

Ницца! Я думал об использовании 'cumsum' тоже, но не мог понять, как реализовать отставание. – nico

+0

Вау, большое спасибо за помощь – martin

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