Come vettorare: impostare un valore in base all'ultima volta che un vettore binario era 1
Domanda
Ho un'altra domanda per principianti R ...
Come posso vettorializzare (evitare per loop in) Codice seguente:
# 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
}
}
Sono bloccato a pensare a SAS Data Step Way e Desperatley in cerca di trattenere ecc. Dove posso trovare alcuni semplici exaples per capire sapply ecc. (R Aiuto via? Sapply è purtroppo complicato per me ... :()
Grazie per il tuo gentile aiuto.
Meglio, samo.
Soluzione
Se ho capito correttamente, il tuo problema è: hai due vettori signal
e mktdataclose
di lunghezza n
, e vuoi creare un nuovo vettore EntryPrices
di lunghezza n
tale che mktdataclose[i]
è il valore di mktdataclose
il Ultimo volta signal
era 1 al momento o prima i
. Puoi farlo senza un ciclo per loop, usando cummax
, una funzione spesso inaspettatamente utile (si noti che questa domanda è simile nel sapore ad alcune delle tue domande precedenti, che sono state risolte allo stesso modo usando questa funzione e cumsum
). Eccoci qui, usando i dati di Gavin:
set.seed(123)
signal <- sample(0:1, 10, replace = TRUE)
mktdataclose <- runif(10, 1, 10)
Il nostro problema è davvero convertire il signal
vettore in un vettore degli indici appropriati:
indices <- cummax( seq_along(signal) * signal)
Questo è esattamente il indices
Vogliamo, tranne lo 0. Ora abbiamo impostato EntryPrices
Estrando i valori a diverso da zero indices
da 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
Altri suggerimenti
Poiché il segnale è 0 e 1 presumo che tu possa vettorializzare con:
EntryPrices * signal
Ecco un'altra soluzione che potresti trovare più dritta. Sto usando PSudo-Data di 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