r - 在 R 中向量化迭代函数的最佳方法是什么?
问题描述
我正在使用一个引用给定个人投资组合价值的函数。要使用此函数,我需要遍历数据框的行并应用此函数:
x$cota <- 100
cotiza <- function(x){
for(i in 1:nrow(x)) {
if (i > 1){
x[i,]$cota <- ((x[i,]$pl - x[i,]$mov)/x[i-1,]$pl) * x[i-1,]$cota
}
return (x)
}
这是该函数应用于的数据框:
data pl mov cota
1 2018-01-01 500.0 250000 100
2 2018-01-02 525.0 0 100
3 2018-01-03 997.2 -100000 100
4 2018-01-04 500.0 0 100
5 2018-01-05 520.0 0 100
此数据帧上的函数输出应如下所示:
data pl mov cota
1 2018-01-01 500.0 250000 100.00
2 2018-01-02 525.0 0 105.00
3 2018-01-03 997.2 -100000 20199.44
4 2018-01-04 500.0 0 10128.08
5 2018-01-05 520.0 0 10533.20
有没有办法让这个函数矢量化,以便我可以将它应用到数据框?
解决方案
由于cota[3]
依赖 的更新值cota[2]
依赖cota[1]
,您不能对此函数进行简单的矢量化。有时您可以通过使用cumsum
、cumprod
或类似的累积函数(它们仍然是迭代但在真正优化的代码中)来作弊,但它依赖于“简单的迭代累积”。然而,在这种情况下,一系列
cota[2] = cota[1] * (pl[2] - mov[2]) / pl[1],
cota[3] = cota[2] * (pl[3] - mov[3]) / pl[2]
如果你更换cota[2]
,你会得到
(cota[1] * (pl[2] - mov[2]) / pl[1]) * (pl[3] - mov[3]) / pl[2]
这实际上是
cota[1] * (pl[2]*pl[3] - pl[2]*mov[3] - pl[3]*mov[2] + mov[2]*mov[3]) / (pl[1] * pl[2])
它不会立即适用于简单的累积运算符。
一些提供各种滚动窗口的函数,特别是zoo::rollapply
,但它们通常for
在引擎盖下进行循环。(从技术上讲,我相信大多数*apply
功能也在for
引擎盖下进行循环,尽管很可能在引擎盖下。)
如果您在使用此功能或类似功能时遇到性能问题,您始终可以使用Rcpp
或类似的加速器。(一旦你进入Rcpp
-territory,你可能会发现原始for
循环会击败矢量化代码,甚至Rcpp
-native 矢量化,尽管这在很大程度上取决于许多其他事情。)
推荐阅读
- image - 如何使用卫星图像检测地表作物成熟度或压力?
- python - 在Python中将字符串拆分为字典
- flutter - 如何在构建方法中使用状态管理?
- java - 如何使用彩色按钮作为用户选择从第二个活动更改我的 MainActivity 的背景颜色?
- ruby-on-rails - 如何使用 Rails 将 ISO 8601 日期转换为整数
- reactjs - ReactJs --- 向儿童发送道具导致儿童渲染出现问题。UI 渲染未发生“NewsLatest.js”
- python - 为什么 randomize 的输出结果重复相同?
- html - 修复移动设备上动画下划线的宽度
- node.js - 如何在猫鼬的同一个文件中导出多个模式
- dynamics-crm - 在 Dynamics CRM Online 中通过 Web API 创建记录时未声明的属性