我想请您就以下问题寻求帮助。
在一个类似表的对象中,每一行都对应一个时间观察值,我想从一个特定变量(:= p0)的上一行中获取值,然后将其乘以另一列的元素(: = returnfactor),并将结果作为另一列(:= p1)的元素写入当前行。
通过两张图片说明,我想从
到
我写了
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
语句。
您真诚的, 正弦
答案 0 :(得分:4)
我们确实可以改善这一点。需要注意的关键是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