Вам не нужно использовать петли, и вам не нужно «оглядываться назад». Вы можете использовать векторизованную функцию cumsum
, чтобы получить то, что вы хотите. Предполагая, что ваши длинные периоды входа / выхода и короткие периоды входа / выхода не перекрываются, вы можете сделать это: Сначала создайте фиктивные сигналы:
n <- 15
zeros <- rep(0,n)
LongEnt <- replace(zeros, c(1, 12), 1)
LongEx <- replace(zeros, c(4, 14), 1)
ShortEnt <- replace(zeros, 6, 1)
ShortEx <- replace(zeros, 10, 1)
Теперь сделайте магию cumsum
, чтобы получить правильный «совокупный» столбец сигнала:
SigLong <- cumsum(LongEnt) - cumsum(LongEx) + LongEx
SigShort <- -cumsum(ShortEnt) + cumsum(ShortEx) - ShortEx
> cbind(LongEnt, LongEx, ShortEnt, ShortEx, Signal = SigLong + SigShort)
LongEnt LongEx ShortEnt ShortEx Signal
[1,] 1 0 0 0 1
[2,] 0 0 0 0 1
[3,] 0 0 0 0 1
[4,] 0 1 0 0 1
[5,] 0 0 0 0 0
[6,] 0 0 1 0 -1
[7,] 0 0 0 0 -1
[8,] 0 0 0 0 -1
[9,] 0 0 0 0 -1
[10,] 0 0 0 1 -1
[11,] 0 0 0 0 0
[12,] 1 0 0 0 1
[13,] 0 0 0 0 1
[14,] 0 1 0 0 1
[15,] 0 0 0 0 0
Обновление . В соответствии с измененным вопросом ОП нам нужно обработать случай произвольной последовательности сигналов входа / выхода и найти периоды между первой записью и соответствующим первым выходом. Вот способ сделать это с очень простыми арифметическими операциями (то есть без дорогих обратных проверок или проверки if / else). Нам просто нужна небольшая модификация функции cumsum
, которую я назову cumplus
- это похоже на cumsum
, за исключением того, что после взятия каждой суммы она заменяет ее на 1 или 0 в зависимости от того, положительна она или нет:
cumplus <- function(y) Reduce(function(a,b) a + b > 0, y, 0, accum=TRUE)[-1]
(Кстати, Reduce
- это хороший способ компактно определить накопительную функцию без явного выписывания цикла for
- подробности см. ?Reduce
).
Теперь возьмем пример сигналов входа / выхода:
LongEnt <- c(1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
0, 1, 0, 0)
LongEx <- c(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
1, 0, 0, 1)
x <- LongEnt - LongEx
z <- cumplus(x)
Это почти то, что мы хотим ... нам просто нужно вставить 1 в конце каждого блока единиц.
z <- z - c(0,pmin(0,diff(z)))
> cbind(LongEnt, LongEx, signal = z)
LongEnt LongEx signal
[1,] 1 0 1
[2,] 0 0 1
[3,] 0 0 1
[4,] 1 0 1
[5,] 0 0 1
[6,] 0 0 1
[7,] 1 0 1
[8,] 0 0 1
[9,] 0 1 1
[10,] 0 0 0
[11,] 0 0 0
[12,] 0 1 0
[13,] 1 0 1
[14,] 0 0 1
[15,] 0 0 1
[16,] 1 0 1
[17,] 0 0 1
[18,] 0 0 1
[19,] 0 1 1
[20,] 0 0 0
[21,] 0 1 0
[22,] 1 0 1
[23,] 0 0 1
[24,] 0 1 1
Работа с короткими входами / выходами, конечно, будет аналогичной.