Как векторизовать: установить значение на основе последнего времени, когда двоичный вектор был 1 - PullRequest
2 голосов
/ 19 марта 2011

У меня есть еще один вопрос для начинающих R ...

Как я могу векторизовать (не использовать цикл) следующий код:

# 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
    }
}

Я застрял в мысли о шаге данных SAS иотчаянные поиски сохранения и т. д. Где я могу найти несколько простых примеров, чтобы понять sapply и т. д. (Помощь через? sapply, к сожалению, сложна для меня ... :()

Спасибо за вашу любезную помощь.

Бест, Само.

Ответы [ 3 ]

3 голосов
/ 19 марта 2011

Если я правильно понял, ваша проблема: у вас есть два вектора signal и mktdataclose длины n, и вы хотите создать новый вектор EntryPrices длины n такой, что mktdataclose[i] значение mktdataclose последнее время signal было 1 в или раньше времени i. Вы можете сделать это без цикла for, используя cummax, часто неожиданно полезную функцию (обратите внимание, что этот вопрос похож на некоторые из ваших предыдущих вопросов, которые были аналогично решены с помощью этой функции и cumsum). Здесь мы используем данные Гэвина:

set.seed(123)
signal <- sample(0:1, 10, replace = TRUE)
mktdataclose <- runif(10, 1, 10)  

Наша задача на самом деле преобразовать вектор signal в вектор с соответствующими индексами:

indices <- cummax( seq_along(signal) * signal)

Это именно то, что нам нужно indices, за исключением 0. Теперь мы устанавливаем EntryPrices, извлекая ненулевые значения indices из 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
0 голосов
/ 22 марта 2011

Вот еще одно решение, которое вы можете найти более простым.Я использую псадо-данные Прасада.

> 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
0 голосов
/ 19 марта 2011

, поскольку сигнал равен 0 и 1, я предполагаю, что вы можете векторизовать с помощью:

EntryPrices * signal
...