我想要一些关于编写更好的R代码的建议。我目前在R中编写了一个循环,它遇到了性能问题。
我无法绕过矢量化它,因为输出数据帧中的每一行都依赖于前面的行,并且它们会迭代地向下滴,所以我编写了一个循环来按顺序读取/写入行。
我的代码示例:
example <- data.frame(a=c(.5,.1,.5,.25),b=c(1,0,2,0),c=c(1,2,3,4),d=c(4,3,2,1))
for (i in 2:nrow(example)) {
if (example[i,1]>0) {
example[i,2]<-example[i,2]+example[i-1,2]*example[i,1]
example[i,3]<-example[i,3]+example[i-1,3]*example[i,1]
example[i,4]<-example[i,4]+example[i-1,4]*example[i,1]
}
}
看看发生了什么:
# before
a b c d
1 0.50 1 1 4
2 0.10 0 2 3
3 0.50 2 3 2
4 0.25 0 4 1
# after
a b c d
1 0.50 1.0000 1.0000 4.000
2 0.10 0.1000 2.1000 3.400
3 0.50 2.0500 4.0500 3.700
4 0.25 0.5125 5.0125 1.925
答案 0 :(得分:11)
我不确定如何通过行操作来避免,但这里有3条建议可以通过 ~X90 来提高性能
换句话说,尝试将代码转换为
indx <- which(example[-1, 1] > 0)
for(i in indx + 1) example[i, -1] <- example[i, -1] + example[i-1, -1] * example[i, 1]
另请注意,此解决方案适用于任何列数
<强>基准强>
set.seed(123)
N <- 1e3
test <- matrix(runif(N * 4), ncol = 4)
example <- as.data.frame(test)
OP <- function(x){
for (i in 2:nrow(x)) {
if (x[i, 1]>0) {
x[i,2]<-x[i,2]+x[i-1,2]*x[i,1]
x[i,3]<-x[i,3]+x[i-1,3]*x[i,1]
x[i,4]<-x[i,4]+x[i-1,4]*x[i,1]
}
}
x
}
David <- function(x){
indx <- which(x[-1, 1] > 0)
for(i in indx + 1) x[i, -1] <- x[i, -1] + x[i-1, -1] * x[i, 1]
x
}
identical(OP(example), as.data.frame(David(test)))
# [1] TRUE
library(microbenchmark)
microbenchmark(OP(example), David(test))
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# OP(example) 243.913429 246.248061 257.672703 247.104350 256.701590 337.375850 100 b
# David(test) 3.020688 3.080685 3.336778 3.133483 3.301797 9.240615 100 a