优化r中的嵌套for循环

优化r中的嵌套for循环,r,tidyverse,R,Tidyverse,我有下面的r代码。它具有嵌套的for循环。如果I+3行的值为零,我想用NA替换数字。它可以很好地用于小数据集,但是,对于大数据集,它会挂起。我假设嵌套for循环不是实现它的有效方法。有人能建议增强代码,最好是tidyverse库吗 x <- data.frame(c1=c(1,2,3,2,1,3), c2=c(4,5,6,2,3,4), c3=c(7,8,9,7,1,6), c4=c(4,0,9

我有下面的r代码。它具有嵌套的for循环。如果I+3行的值为零,我想用NA替换数字。它可以很好地用于小数据集,但是,对于大数据集,它会挂起。我假设嵌套for循环不是实现它的有效方法。有人能建议增强代码,最好是tidyverse库吗

x <- data.frame(c1=c(1,2,3,2,1,3),
                c2=c(4,5,6,2,3,4),
                c3=c(7,8,9,7,1,6),
                c4=c(4,0,9,1,5,0),
                c5=c(3,8,0,7,3,6),
                c6=c(2,8,5,0,5,7),
                row.names = c("r1","r2","r3","r4","r5","r6"))

for( i in 1:nrow(x)){
  for(j in 1:3){
    if (x[i, j+3] == 0){
      x[i, j] <- NA
    }
  }
}

行上的循环不是必需的,您可以使用
ifelse
对外部循环进行矢量化:

x[1:3] <- lapply(1:3, function(n) ifelse(x[[n+3]] == 0, NA, x[[n]]))
x
#   c1 c2 c3 c4 c5 c6
#r1  1  4  7  4  3  2
#r2 NA  5  8  0  8  8
#r3  3 NA  9  9  0  5
#r4  2  2 NA  1  7  0
#r5  1  3  1  5  3  5
#r6 NA  4  6  0  6  7

x[1:3]我想知道速度是否真的是目标矩阵是否最好?是的,我在寻找可能的最佳速度,因为实际的数据集可能只有1000万行。@zacdav我想说数据帧或矩阵是否取决于OP以后想用它做什么。在我的测试中,使用
xm=as.matrix,matrix似乎要快得多(x) 
使用
xm[,1:3][xm[,4:6]==0]@zacdav确实如此。但请记住,首先必须将大数据帧转换为矩阵,这是非常昂贵的。通过(1)将data.frame转换为矩阵(2)交换i和j循环,您可能会看到性能提高(数据在内存中按列排列,因此在最内部的循环中迭代一列中的所有条目会更快。
x[1:3] <- lapply(1:3, function(n) ifelse(x[[n+3]] == 0, NA, x[[n]]))
x
#   c1 c2 c3 c4 c5 c6
#r1  1  4  7  4  3  2
#r2 NA  5  8  0  8  8
#r3  3 NA  9  9  0  5
#r4  2  2 NA  1  7  0
#r5  1  3  1  5  3  5
#r6 NA  4  6  0  6  7
x[1:3][x[4:6] == 0] <- NA
x
#   c1 c2 c3 c4 c5 c6
#r1  1  4  7  4  3  2
#r2 NA  5  8  0  8  8
#r3  3 NA  9  9  0  5
#r4  2  2 NA  1  7  0
#r5  1  3  1  5  3  5
#r6 NA  4  6  0  6  7