Cómo vectorizar: establecer un valor basado en la última vez que un vector binario fue 1

StackOverflow https://stackoverflow.com/questions/5361878

  •  27-10-2019
  •  | 
  •  

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.

¿Fue útil?

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top