在没有包的情况下根据循环中的上一行计算一行

时间:2019-07-09 13:48:17

标签: r loops

我正在尝试创建一个循环(不使用包)来计算数组的行。矩阵的每一行都是使用前一行的值之一计算的(在代码中,第二行的变量B是前一行的C变量的值) 。我的尝试写在下面:

df=data.frame(matrix(ncol = 4, nrow = 5))
names(df)=c("A", "B", "C", "D")

for (i in 1:nrow(df){
  df$A<-c(0, 0.25, 0.50, 0.75, 1.00)
  df$B<-ifelse(df$A==0, 0, C[i-1])
  df$C<-df$A*df$B)+1
  df$D<-df$C+5
}
df

预期结果是:

     A    B    C    D
1 0.00 0.00 1.00 6.00
2 0.25 1.00 1.25 6.25
3 0.50 1.25 1.63 6.63
4 0.75 1.63 2.22 7.22
5 1.00 2.22 3.22 8.22

我在做什么错了?

1 个答案:

答案 0 :(得分:2)

在循环内部,必须为给定的循环迭代将列的子集添加到正在处理的行(行i)中。否则,您每次都要对整列进行分配,而不仅仅是一行。另外,A和D的创建也不需要循环。

df$A <- c(0, 0.25, 0.50, 0.75, 1.00)
for(i in 1:nrow(df)){
  df$B[i] <- ifelse(df$A[i] == 0, 0, df$C[i-1])
  df$C[i] <- df$A[i]*df$B[i] + 1
}
df$D <- df$C + 5

您也可以使用Reduce来做到这一点,但是对于是否更好,尚无共识,许多人会说将Reduceaccumulate = T一起使用比使用循环更糟糕。

df$A <- c(0, 0.25, 0.50, 0.75, 1.00)
df[, c('B', 'C')] <- 
  do.call(rbind, 
          Reduce(function(x, A) (A != 0)*x[2]*c(1, A) + 0:1, 
                 df$A, init = c(0, 0), accumulate = T))[-1,]
df$D <- df$C + 5