Сохранение отставшего значения для соединения к конечному значению - PullRequest
1 голос
/ 24 апреля 2019

Я хотел бы попросить вашей помощи по следующей проблеме.

В табличном объекте, где каждая строка соответствует наблюдению во времени, я хотел бы получить значение из предыдущей строки для одной конкретной переменной (: = p0), умножить его на элемент другого столбца (: = returnfactor) и записать результат в текущую строку как элемент другого столбца (: = p1).

Иллюстрированный через две картинки, я хочу перейти от

enter image description here

до

enter image description here .

Я написал

matrix <- cbind (    
                1:10,
                1+rnorm(10, 0, 0.05),
                NA,
                NA
                )
colnames(matrix)    <-  c("timeid", "returnfactor", "p0", "p1")
matrix[1, "p0"]     <-  100
for (i in 1:10)
    {
    if (i==1)
        {
            matrix[i, "p1"]    <-  matrix[1, "p0"] * matrix[i, "returnfactor"]
        }
    else
        {
           matrix[i, "p0"]    <-  matrix[i-1, "p1"] 
           matrix[i, "p1"]    <-  matrix[i, "p0"] * matrix[i, "returnfactor"]
        }

     }

То есть я реализовал то, чего хотел бы достичь, используя цикл. Однако этот цикл слишком медленный. Очевидно, я новичок в R.

Не могли бы вы дать мне подсказку, как улучшить скорость, используя возможности, которые предлагает R? Я предполагаю, что здесь нет необходимости в цикле, хотя у меня нет подхода, как сделать это еще. В SAS я использовал чтение фреймов данных по строкам и retain -статей в шаге данных.

С уважением, Sinistrum

1 Ответ

4 голосов
/ 24 апреля 2019

Мы действительно можем улучшить это.Ключевым моментом, на который следует обратить внимание, является то, что значения p0 и p1 включают в основном кумулятивные продукты.В частности, у нас есть

mat[, "p1"] <- mat[1, "p0"] * cumprod(mat[, "returnfactor"])
mat[-1, "p0"] <- head(mat[, "p1"], -1)

, где head(mat[, "p1"], -1) просто берет все mat[, "p1"] за исключением последнего элемента.Это дает

#       timeid returnfactor        p0        p1
#  [1,]      1    0.9903601 100.00000  99.03601
#  [2,]      2    1.0788946  99.03601 106.84941
#  [3,]      3    1.0298117 106.84941 110.03478
#  [4,]      4    0.9413212 110.03478 103.57806
#  [5,]      5    0.9922179 103.57806 102.77200
#  [6,]      6    0.9040545 102.77200  92.91149
#  [7,]      7    0.9902371  92.91149  92.00440
#  [8,]      8    0.8703836  92.00440  80.07913
#  [9,]      9    1.0657001  80.07913  85.34033
# [10,]     10    0.9682228  85.34033  82.62846
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...