簡體   English   中英

在 R - 使用百分比返回計算向量中的值

[英]In R - Calculate values in a vector using percentage returns

我有一個 data.table 由一行組成,其中包含一個值和一個百分比回報列表。 我想通過按順序使用百分比回報將此信息轉換為值。 下面是一個例子。 它工作正常,但我想加快速度並提高效率。 在示例中,我只顯示了四個返回期……實際上,我有數百個。 此外,我需要並行進行數萬次這種轉換。 因此,任何加速都會有所幫助。 是否有任何 R 功能/包可以更有效地執行此類操作? 謝謝你的時間!

library(data.table)
library(tidyr)
a <- 2
b <- 4
x <- data.table(awq = c(0.1), R1 = c(0.15), R2 = c(-0.05), R3 = c(0.70), R4 = c(-0.1))
print(x)
    awq   R1    R2  R3   R4
 1: 0.1 0.15 -0.05 0.7 -0.1
tmp1 <- as.data.table(tidyr::gather(x, period, return, -awq, factor_key=F))
setnames(tmp1, old = c("return"), new = c("ret"))
tmp1[period == "R1", v := awq*ret + awq]
for(i in 2:4) {
  tmp1[i, v := tmp1[i, ret] * abs(tmp1[(i-1), v]) + tmp1[(i-1), v]]
}
tmp1[v < 0, v := 0]
tmp1 <- tmp1[, .(period, v)]
tmp1[, a := a]
tmp1[, b := b]
tmp1 <- as.data.table(pivot_wider(tmp1, names_from = period, values_from = c(v)))
print(tmp1)
   a b    R1      R2       R3        R4
1: 2 4 0.115 0.10925 0.185725 0.1671525

@akrun 對cumprod的評論很到位:

myfunc <- function(awq, rest) as.data.table(awq * t(apply(1 + rest, 1, cumprod)))

### Another row
x <- data.table(awq = c(0.1,0.2), R1 = c(0.15), R2 = c(-0.05), R3 = c(0.70), R4 = c(-0.1))

x[, myfunc(awq, .SD[,R1:R4])]
#         R1      R2       R3        R4
# [1,] 0.115 0.10925 0.185725 0.1671525
# [2,] 0.230 0.21850 0.371450 0.3343050

您可以使用幾種技術來擴充原始框架:

cbind(x, x[, myfunc(awq, .SD[,R1:R4])])
#    awq   R1    R2  R3   R4    R1      R2       R3        R4
# 1: 0.1 0.15 -0.05 0.7 -0.1 0.115 0.10925 0.185725 0.1671525
# 2: 0.2 0.15 -0.05 0.7 -0.1 0.230 0.21850 0.371450 0.3343050

x[, c("S1","S2","S3","S4") := myfunc(awq, .SD[,R1:R4]) ][]
#    awq   R1    R2  R3   R4    S1      S2       S3        S4
# 1: 0.1 0.15 -0.05 0.7 -0.1 0.115 0.10925 0.185725 0.1671525
# 2: 0.2 0.15 -0.05 0.7 -0.1 0.230 0.21850 0.371450 0.3343050

第一個缺點是列名重復。 后者的缺點是需要先驗地知道所涉及的列數。


myfunc主要是單板,這可以進一步簡化:

x[, awq*t(apply(1+.SD[,R1:R4],1,cumprod)) ]
#         R1      R2       R3        R4
# [1,] 0.115 0.10925 0.185725 0.1671525
# [2,] 0.230 0.21850 0.371450 0.3343050

使用我之前提到的所有“增強”步驟。

此外,我們還可以使用rowCumprods中的matrixStats

library(matrixStats)
library(data.table)
x[, names(x)[-1] := as.data.table(awq * rowCumprods( as.matrix(.SD+ 1))), 
      .SDcols = patterns("^R")][]
#  awq    R1      R2       R3        R4
#1: 0.1 0.115 0.10925 0.185725 0.1671525

此外,在 OP 顯示的原始腳本中, gather/pivot_wider可以替換為 data.table 中的melt/dcast data.table

tmp1 <- melt(x, id.var = 'awq', variable.name = 'period', value.name = 'ret')
tmp1[period == "R1", v := awq*ret + awq]

並且for循環可以替換為Reduce

tmp1[, v := Reduce(`*`, ret + 1, accumulate = TRUE) * awq]
dcast(tmp1, awq ~ period, value.var = 'v')
#   awq    R1      R2       R3        R4
#1: 0.1 0.115 0.10925 0.185725 0.1671525

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM