Использование Rollapply на двух столбцах
-
13-10-2019 - |
Вопрос
Я пытаюсь сделать что -то подобное, что просил здесь И, к сожалению, я не могу решить это.
Это мой кадр данных (данные), временной ряд цен:
Date Price Vol
1998-01-01 200 0.3
1998-01-02 400 0.4
1998-01-03 600 -0.2
1998-01-04 100 0.1
...
1998-01-20 100 0.1
1998-01-21 200 -0.4
1998-01-21 500 0.06
....
1998-02-01 100 0.2
1998-02-02 200 0.4
1998-02-03 500 0.3
1998-02-04 100 0.1
etc.
Я хотел бы сказать R,
- Возьмите 1 -е значение «VOL» и разделите его на 20 -е значение «Цена», затем
- Возьмите 2 -е значение «VOL» и разделите его на 21 -е значение «Цена», тогда.
- Возьмите 3 -е значение «VOL» и разделите его на 22 -е значение «Цена», затем
- и т.п.
В другом посте я смог использовать эту функцию для расчета возврата в течение периода удержания 20 дней:
> data.xts <- xts(data[, -1], data[, 1])
> hold <- 20
> f <- function(x) log(tail(x, 1)) - log(head(x, 1))
> data.xts$returns.xts <- rollapply(data.xts$Price, FUN=f,
width=hold+1, align="left", na.pad=T)
Есть ли способ сделать что -то очень похожее для проблемы, указанной выше? Так что -то вроде
f1 <- function(x,y) head(x, 1) / tail(y,1)
где x - это «vol», а Y - «цена», а затем нанести «Rollapply»?
Большое спасибо
Обновление: @ Dr G: Спасибо за ваши предложения. С небольшим изменением он сделал то, что я хотел!
data.xts <- xts(data[, -1], data[, 1])
hold <- 20
data.xts$quo <- lag(data.xts[,2], hold) / data.xts[,1]
Теперь моя проблема в том, что полученная кадр данных выглядит следующим образом:
Date Price Vol quo
1 1998-01-01 200 0.3 NA
2 1998-01-02 400 0.4 NA
3 1998-01-03 600 -0.2 NA
4 1998-01-04 100 0.1 NA
...
21 1998-01-20 180 0.2 0.003
Я знаю, что должен быть НА в качестве результата, но только для последних 20 наблюдений, а не первых 20. Формула, указанная выше, вычисляет правильные значения, однако ставит их, начиная с 21 -го ряда вместо первой строки. Вы знаете, как я мог бы это изменить?
Решение
Это на самом деле проще, чем это. Просто сделай это:
data.xts <- xts(data[, -1], data[, 1])
hold <- 20
returns.xts = data.xts[,2] / lag(data.xts[,1], hold)
На самом деле для этого, используя зоопарк вместо XTS, также будет работать:
data.zoo<- zoo(data[, -1], data[, 1])
hold <- 20
returns.zoo = data.zoo[,2] / lag(data.zoo[,1], -hold)
Единственное, что меняется, - это признак лагов (соглашение о зоопарке отличается от XTS)
Другие советы
Использовать by.column = FALSE
в rollapply
. Анкет Чтобы использовать опубликованные данные, мы разделим объем в первом ряду по цене в 3 -м ряду и т. Д. Для целей воспроизводимой иллюстрации:
library(zoo)
Lines <- "Date Price Vol
1998-01-01 200 0.3
1998-01-02 400 0.4
1998-01-03 600 -0.2
1998-01-04 100 0.1
1998-01-20 100 0.1
1998-01-21 200 -0.4
1998-01-21 500 0.06
1998-02-01 100 0.2
1998-02-02 200 0.4
1998-02-03 500 0.3
1998-02-04 100 0.1"
# read in and use aggregate to remove all but last point in each day.
# In reality we would replace textConnection(Lines) with something
# like "myfile.dat"
z <- read.zoo(textConnection(Lines), header = TRUE,
aggregate = function(x) tail(x, 1))
# divide Volume by the Price of the point 2 rows ahead using by.column = FALSE
# Note use of align = "left" to align with the volume.
# If we used align = "right" it would align with the price.
rollapply(z, 3, function(x) x[1, "Vol"] / x[3, "Price"], by.column = FALSE,
align = "left")
# and this is the same as rollapply with align = "left" as above
z$Vol / lag(z$Price, 2)
# this is the same as using rollapply with align = "right"
lag(z$Vol, -2) / z$Price
Кстати, обратите внимание, что zoo
использует ту же соглашение для знака lag
как делает R
но xts
использует противоположное соглашение, поэтому, если вы конвертируете выше xts
Вам придется отрицать лаги.
Вам просто нужно использовать
data.xts$quo <- data.xts[,2] / lag( data.xts[,1], -hold)