R中循环的替代方案
可能重复:R中循环的替代方案,r,for-loop,R,For Loop,可能重复: 我有几个关于循环的问题。我知道R在矢量化计算中工作得更快,我想修改下面的代码来利用这一点。在论坛上查看其他一些答案时,sapply函数似乎能够替换内部for循环,但我正在生成一个零向量,因此存在一个错误。陶仍然是1000,我认为这是造成问题的原因 我主要关心的是速度,因为我需要围绕整个算法创建一个循环,并以不同的V和n大小绘制曲线,以便进行进一步的分析 谢谢你的帮助 备选循环 tao=1000 L=(道-1) n=10 V=5 I=10000 V_s=矩阵(形式(I),I,1) V
我有几个关于循环的问题。我知道R在矢量化计算中工作得更快,我想修改下面的代码来利用这一点。在论坛上查看其他一些答案时,sapply函数似乎能够替换内部for循环,但我正在生成一个零向量,因此存在一个错误。陶仍然是1000,我认为这是造成问题的原因 我主要关心的是速度,因为我需要围绕整个算法创建一个循环,并以不同的V和n大小绘制曲线,以便进行进一步的分析 谢谢你的帮助 备选循环
tao=1000
L=(道-1)
n=10
V=5
I=10000
V_s=矩阵(形式(I),I,1)
V_b=矩阵(形式(I),I,1)
signal假设显式循环是正确的计算,请尝试以下操作:
signal[j]<- signal[j] +
sapply((j-n+1):j,
FUN = function(iter){
abs(V_s[iter] - V_b[iter])
}, V_s = V_s, V_b = V_b)
signal[j]矢量化计算并不总是意味着使用*apply函数
例如,您可以通过使用向量索引替换第二个For循环来简化和加速事情:
for(j in (n:L)){
sel <- (j-n+1):j
signal[j] <- sum(abs(V_s[sel] - V_b[sel])) / (n*V)
}
而对于for
循环,它是:
utilisateur système écoulé
0.06 0.00 0.06
顺便说一句,你不应该用tao
这个名字来表示两种不同的东西。使用过滤器,你甚至可以在没有任何循环的情况下进行计算(而sapply
只不过是一个隐藏的循环)
这正是卷积滤波器所做的——将一些值相加——以一般形式乘以一些权重。作为权重,我们为所有值选择1/(n*V)
,这与您在外部循环中执行的标准化相对应。最后一个参数,sides=1
只是告诉过滤器只从过去获取值(sides=2
意味着sum(absdif[(j-n/2):(j+n/2)])
)
最后一行只填充开头的NA
值(过滤器没有足够的数据来计算总和-这等于跳过第一个n
值)
最后,一些时间安排:
您的完整循环解决方案:
User System total
0.037 0.000 0.037
朱巴问题的解决办法:
User System total
0.007 0.000 0.008
使用过滤器的解决方案:
User System total
0.000 0.000 0.001
请注意,过滤器的概念是非常好的研究,可以做得非常快
编辑:
如?filter
中所述,R不使用标准filter
命令的快速傅里叶变换。通常,FFT是实现卷积的最有效方法。但是,甚至可以通过将filter命令替换为
signal <- convolve(absdif[1:L], rep(1/(n*V), n), type='filter')
signal是否有理由使用矩阵而不是向量,而V_s、V_b和signal似乎只有一列?如果将browser()
放入for(tao)循环中,您将能够检查函数的内部工作,并查看发生了什么。@juba,我在后面的方法中使用了矩阵格式,但本质上是这样的,这是一个矢量。关于加速R代码的一般建议是:完全正确。矢量化几乎总能提高速度*apply
函数很少使用。这大大缩短了处理时间,感谢您的帮助和输入。很好的解决方案,不知道如何使用filter()
+1,虽然filter也可能是一个伪装的循环…@PaulHiemstra可能,但似乎是一个非常有效的循环:)@Paul Well,矢量化始终只是一个隐藏的循环,但其间有不同的优化步骤。过滤器的优化水平应与abs
操作符的优化水平相同。但是,在思考的同时,我们仍然可以做得更好。请稍后查看我的编辑。感谢您的回答,我运行了您的建议并收到了与预期不同的输出。我应该用两个for循环替换您的解决方案?
signal[j] <- sum(absdif[j-n+1:j])
User System total
0.037 0.000 0.037
User System total
0.007 0.000 0.008
User System total
0.000 0.000 0.001
signal <- convolve(absdif[1:L], rep(1/(n*V), n), type='filter')