Cómo vectorizar: establecer un valor basado en la última vez que un vector binario fue 1
Pregunta
Tengo otra pregunta para principiantes ...
¿Cómo puedo vectorizar (evitar el bucle?) El siguiente código:
# algorithm for getting entry prices (when signal > 0): look back from current
# position until you find first signal > 0,
# `mktdataclose` at that time is entry price
# `entryPrices` is an xts object representing entry prices
# if entryPrices are not available (is.null == TRUE) then wee need to reconstruct
# them from signal (xts object with 1 when entry signal triggered and 0
# otherwise) and close prices available in mktdataclose (an xts object with the
# same length as signal and same dates just that it represents closing prices)
EntryPrices <- entryPrices
if (is.null(EntryPrices)) {
# get entryprices as close prices on buy signal
EntryPrices <- ifelse(signal > 0, mktdataclose, 0)
entryPrice <- 0
for (i in 1:NROW(signal)) {
if (signal[i] > 0) entryPrice <- mktdataclose[i]
EntryPrices[i] <- entryPrice
}
}
Estoy atrapado al pensar en los datos de SAS y desesperatley buscando retener, etc. ¿Dónde puedo encontrar algunas exaples simples para comprender el zarzito, etc.?
Gracias por su amable ayuda.
Lo mejor, Samo.
Solución
Si entendí correctamente, su problema es: tiene dos vectores signal
y mktdataclose
de longitud n
, y quieres crear un nuevo vector EntryPrices
de longitud n
tal que mktdataclose[i]
es el valor de mktdataclose
la ultimo tiempo signal
fue 1 en o antes del tiempo i
. Puedes hacer esto sin un bucle for, usando cummax
, una función a menudo inesperadamente útil (tenga en cuenta que esta pregunta es similar en sabor a algunas de sus preguntas anteriores, que se resolvieron de manera similar utilizando esta función y cumsum
). Aquí vamos, usando los datos de Gavin:
set.seed(123)
signal <- sample(0:1, 10, replace = TRUE)
mktdataclose <- runif(10, 1, 10)
Nuestro problema es realmente convertir el signal
vector en un vector de los índices apropiados:
indices <- cummax( seq_along(signal) * signal)
Esto es exactamente el indices
Queremos, excepto por el 0. Ahora nos pusimos EntryPrices
extrayendo los valores en el no cero indices
de mktdataclose
:
EntryPrices <- c( rep(0, sum(indices==0)), mktdataclose[ indices ])
> cbind(signal, indices, mktdataclose, EntryPrices)
signal indices mktdataclose EntryPrices
[1,] 0 0 9.611500 0.000000
[2,] 1 2 5.080007 5.080007
[3,] 0 2 7.098136 5.080007
[4,] 1 4 6.153701 6.153701
[5,] 1 5 1.926322 1.926322
[6,] 0 5 9.098425 1.926322
[7,] 1 7 3.214790 3.214790
[8,] 1 8 1.378536 1.378536
[9,] 1 9 3.951286 3.951286
[10,] 0 9 9.590533 3.951286
Otros consejos
Dado que la señal es 0 y 1 supongo que puede vectorizar con:
EntryPrices * signal
Aquí hay otra solución que puede encontrar más directamente. Estoy usando los psudo-datos de Prasad.
> EntryPrices <- ifelse(signal > 0, mktdataclose, NA)
> EntryPrices <- na.locf(EntryPrices, na.rm=FALSE)
> cbind(signal,mktdataclose,EntryPrices)
signal mktdataclose EntryPrices
[1,] 0 9.611500 NA
[2,] 1 5.080007 5.080007
[3,] 0 7.098136 5.080007
[4,] 1 6.153701 6.153701
[5,] 1 1.926322 1.926322
[6,] 0 9.098425 1.926322
[7,] 1 3.214790 3.214790
[8,] 1 1.378536 1.378536
[9,] 1 3.951286 3.951286
[10,] 0 9.590533 3.951286