Comment vectoriser: définir une valeur basée sur la dernière fois un vecteur binaire était 1
Question
J'ai une autre question R débutant ...
Comment puis-je vectoriser (pour éviter boucle) de code suivant:
# 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
}
}
Je suis coincé à penser chemin et desperatley étape de données SAS recherche, etc. Où conserve-je trouver des exaples simples pour comprendre sapply etc (aide r via? Sapply est malheureusement compliqué pour moi ... :()
Je vous remercie de votre aimable aide.
Best, Samo.
La solution
Si je comprends bien, votre problème est la suivante: vous avez deux vecteurs signal
et mktdataclose
de n
de longueur, et que vous voulez créer un nouveau vecteur EntryPrices
de n
de longueur telle que mktdataclose[i]
est la valeur de mktdataclose
dernier temps signal
était de 1 à ou avant l'heure i
. Vous pouvez le faire sans boucle, en utilisant cummax
, une fonction souvent de façon inattendue utile (Notez que cette question est semblable à la saveur à certaines de vos questions précédentes, qui ont été résolus à l'aide de la même cette fonction et cumsum
). Ici, nous allons, en utilisant les données de Gavin:
set.seed(123)
signal <- sample(0:1, 10, replace = TRUE)
mktdataclose <- runif(10, 1, 10)
Notre problème est vraiment convertir le vecteur signal
dans un vecteur des indices appropriés:
indices <- cummax( seq_along(signal) * signal)
Ceci est exactement le indices
que nous voulons, à l'exception du 0. Nous EntryPrices
ensemble en extrayant les valeurs au indices
non nul 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
Autres conseils
puisque le signal est 0 et 1 je suppose que vous pouvez vectoriser avec:
EntryPrices * signal
Voici une autre solution que vous trouverez peut-être plus simple. J'utilise psudo-données 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