【问题标题】:Calculate a rolling percent change in R计算 R 的滚动百分比变化
【发布时间】:2021-12-30 18:27:09
【问题描述】:

我试图根据股票的收盘价计算 R 的 20 天滚动百分比变化。以下是最近 100 天收盘价数据的样本。 df$Close[1] 是最近一天,df$Close[2] 是前一天,以此类推。

    df$Close
   [1] 342.94 346.22 346.18 335.24 330.45 334.20 325.45 333.79 334.90 341.66 333.74 334.49 329.75 329.82 330.56 322.81 317.87 306.84
  [19] 310.39 310.60 324.46 338.03 333.12 341.06 337.25 341.01 345.30 338.69 340.77 342.96 347.56 340.89 327.74 327.64 335.37 338.62
  [37] 341.13 335.85 331.62 328.08 329.98 323.57 316.92 312.22 315.81 328.69 324.61 341.88 340.78 339.99 335.34 324.76 328.53 324.54
  [55] 323.77 325.45 330.05 329.22 333.64 332.96 326.23 343.01 339.39 339.61 340.65 353.58 352.96 345.96 343.21 357.48 355.70 364.72
  [73] 373.06 373.92 376.53 376.51 378.69 378.00 377.57 382.18 376.26 375.28 382.05 379.38 380.66 372.63 364.38 368.39 365.51 363.35
  [91] 359.37 355.12 355.45 358.45 366.56 363.18 362.65 359.96 361.13 361.61 

以前,我使用以下代码来计算百分比变化:

PercChange(df, Var = 'Close', type = 'percent', NewVar = 'OneMonthChange', slideBy = 20)

这给了我以下输出:

df$OneMonthChange


  [1]  5.695617e-02  2.422862e-02  3.920509e-02 -1.706445e-02 -2.016308e-02 -1.997009e-02 -5.748624e-02 -1.446751e-02 -1.722569e-02
  [10] -3.790530e-03 -3.976292e-02 -1.877438e-02  6.132910e-03  6.653644e-03 -1.434237e-02 -4.668950e-02 -6.818515e-02 -8.637785e-02
  [19] -6.401906e-02 -5.327969e-02 -1.672829e-02  4.468894e-02  5.111700e-02  9.237076e-02  6.788892e-02  3.748213e-02  6.373802e-02
  [28] -9.330759e-03 -2.934445e-05  8.735551e-03  3.644063e-02  4.966745e-02 -2.404651e-03  9.551981e-03  3.582790e-02  4.046705e-02
  [37]  3.357067e-02  2.013851e-02 -6.054430e-03 -1.465642e-02  1.149496e-02 -5.667473e-02 -6.620702e-02 -8.065134e-02 -7.291942e-02
  [46] -7.039425e-02 -8.032072e-02 -1.179327e-02 -7.080213e-03 -4.892581e-02 -5.723925e-02 -1.095635e-01 -1.193642e-01 -1.320603e-01
  [55] -1.401216e-01 -1.356139e-01 -1.284428e-01 -1.290476e-01 -1.163493e-01 -1.287875e-01 -1.329666e-01 -8.598913e-02 -1.116608e-01
  [64] -1.048289e-01 -1.051069e-01 -5.112310e-02 -3.134091e-02 -6.088656e-02 -6.101064e-02 -1.615522e-02 -1.021232e-02  2.703312e-02
  [73]  4.954283e-02  4.315804e-02  2.719882e-02  3.670356e-02  4.422997e-02  5.011668e-02  4.552377e-02  5.688449e-02  3.507469e-02
  [82]  3.391465e-02  6.444333e-02  8.011616e-02  8.157409e-02  4.583216e-02  1.691226e-02 -1.310009e-02 -6.253229e-03 -2.445900e-02
  [91] -2.817816e-02  1.119052e-02  2.662970e-02  4.914242e-02  8.787654e-02  6.454450e-02  5.280729e-02  3.546875e-02  2.567525e-02
 [100]  2.392683e-02

PercChange 函数现已弃用,我需要找到一个新函数来替换它。本质上,我需要一个函数来计算 df$Close[1:20] 的百分比变化(这将是第 1 天的收盘价减去第 20 天的收盘价,除以第 20 天的收盘价),然后滚动到 [2:21]对于下一行,然后是 [3:22]、[4:23],依此类推。

提前致谢!

【问题讨论】:

  • 你将如何计算最后的部分值?
  • 如果没有完整的 20 天收盘价数据,这些将显示为零
  • 在您的数据中,您有 100 个值,这意味着窗口为 20,您应该返回 80 个值,但您有 100 个值返回。这怎么可能?
  • 这里的值比显示的要多得多。我只是抓取了整个数据集的一小部分样本。我想我应该只包含 OneMonthChange 中的前 80 个值
  • @jgg96 如果您将dput(df)dput(head(df, 100)) 的输出添加到您的问题中,人们会更容易提供帮助。谢谢。

标签: r


【解决方案1】:

这是一个简单的 Base R 解决方案:

PercChange<- function(x, slideBy){
  -diff(x, slideBy)/ tail(x, -slideBy)
}

PercChange(df$Close, slideBy = 20)

 [1]  5.695617e-02  2.422862e-02  3.920509e-02 -1.706445e-02
 [5] -2.016308e-02 -1.997009e-02 -5.748624e-02 -1.446751e-02
 [9] -1.722569e-02 -3.790530e-03 -3.976292e-02 -1.877438e-02

如果您希望返回一个数据框,请将其修改为:

PercChange<- function(data, Var, NewVar, slideBy){
  x <- data[[Var]]
  data[NewVar] <- c(-diff(x, slideBy)/ tail(x, -slideBy), numeric(slideBy))
  data
}

PercChange(df, Var = 'Close', NewVar = 'OneMonthChange', slideBy = 20)

数据:

df <- structure(list(Close = c(342.94, 346.22, 346.18, 335.24, 330.45, 
334.2, 325.45, 333.79, 334.9, 341.66, 333.74, 334.49, 329.75, 
329.82, 330.56, 322.81, 317.87, 306.84, 310.39, 310.6, 324.46, 
338.03, 333.12, 341.06, 337.25, 341.01, 345.3, 338.69, 340.77, 
342.96, 347.56, 340.89, 327.74, 327.64, 335.37, 338.62, 341.13, 
335.85, 331.62, 328.08, 329.98, 323.57, 316.92, 312.22, 315.81, 
328.69, 324.61, 341.88, 340.78, 339.99, 335.34, 324.76, 328.53, 
324.54, 323.77, 325.45, 330.05, 329.22, 333.64, 332.96, 326.23, 
343.01, 339.39, 339.61, 340.65, 353.58, 352.96, 345.96, 343.21, 
357.48, 355.7, 364.72, 373.06, 373.92, 376.53, 376.51, 378.69, 
378, 377.57, 382.18, 376.26, 375.28, 382.05, 379.38, 380.66, 
372.63, 364.38, 368.39, 365.51, 363.35, 359.37, 355.12, 355.45, 
358.45, 366.56, 363.18, 362.65, 359.96, 361.13, 361.61)), class = "data.frame", row.names = c(NA, 
-100L))

【讨论】:

  • 非常感谢!!!!这正是我所需要的!
  • 我试图投票,但它说我还没有足够的声誉
  • 我代表你投票:D
【解决方案2】:

tidyverse 方法

library(tidyr)
library(dplyr)

df %>% mutate(OneMonthChange=(Close-lead(Close, 20))/lead(Close, 20), 
  OneMonthChange=replace_na(OneMonthChange,0))
     Close OneMonthChange
1   342.94   5.695617e-02
2   346.22   2.422862e-02
3   346.18   3.920509e-02
4   335.24  -1.706445e-02
5   330.45  -2.016308e-02
6   334.20  -1.997009e-02
etc...

【讨论】:

  • 非常感谢您的回答!我收到一条错误消息,说找不到函数“replace_na”。我需要为这个功能下载某个库吗?
  • @jgg96 是的,抱歉,没有明确的包含在代码框中,只是写在了正文中。已添加!
  • 谢谢安德烈!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-22
  • 1970-01-01
  • 2018-06-20
  • 2013-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多