在R中生成新列,如果满足条件则保留值,否则使用上一列

Generate new column in R, keep value if it meets a condition, else use the previous column

我正在使用 R 生成两个长度为 20 的独立列向量,我想向它们添加 150 个额外的列向量,并根据先前列中的值保留新值。我使用以下代码启动两个列向量:

n <- 20
set.seed(4)
x0 <- runif(n = n, min = -9, max = 9)
set.seed(16)
y0 <- runif(n = n, min = -9, max = 9)

这为我提供了每个向量的第一列。然后,我根据这些值生成第二列。但是,我只想在满足特定条件的情况下保留每行的新值。如果他们不满足条件,我希望新列值被旧列值替换。下面的代码是生成新列,分析它的值,并保留新值或用旧值替换它,然后重复150次迭代:

iter <- 150
for(j in 1:iter){
  St <- runif(n = n, min = 0, max = 2)
  dt <- runif(n = n, min = 0, max = 2*pi)
  dx <- cos(dt)
  dy <- sin(dt)
  xm <- St*dx
  ym <- St*dy
  x0 <- cbind(x0, xm)
  y0 <- cbind(y0, ym)
  xall <- t(apply(x0, 1, cumsum))
  yall <- t(apply(y0, 1, cumsum))
  for(i in 1:n){
    if(xall[i,j+1]<=3 & xall[i,j+1]>=-3 & yall[i,j+1]<=3 & yall[i,j+1]>=-3){
      xall[i,j+1] <- xall[i,j+1]
      yall[i,j+1] <- yall[i,j+1]
    }
    else if(xall[i,j]>3 | xall[i,j]<(-3) | yall[i,j]>3 | yall[i,j]<(-3)){
      xall[i,j+1] <- xall[i,j+1]
      yall[i,j+1] <- yall[i,j+1]
    }
    else{
      xall[i,j+1] <- xall[i,j]
      yall[i,j+1] <- yall[i,j]
    }
  }
}

“xall”和“yall”数组不断向其添加列,一一迭代 150 次。每次迭代和添加新列后,应遵循以下规则:

我将在此处给出我的代码的示例输出,该代码目前无法正常工作:

> xall[3,10:14]
      x10       x11       x12       x13       x14 
-3.657078 -2.558799 -2.790860 -2.797736 -3.372856 

> yall[3,10:14]
      y10       y11       y12       y13       y14  
-1.938531 -2.991856 -2.597014 -2.694228 -3.363116 

从 x10 和 y10 开始。其中至少有一个超出范围 [-3,3],因此他们应该接受第 11 列的新列值(按预期工作)。在第 11 列中,x11 和 y11 都在范围内,但下一列 x12 和 y12 也都在范围内,因此它们应该接受新值(按预期工作)。跳转到 x13 和 y13,两者都在范围内,但至少有一个下一个值不在范围内。所以 x14 和 y14 应该复制以前的值(没有按预期工作)。目标是为 x14 和 y14 得到这样的东西:

> xall[3,10:14]
      x10       x11       x12       x13       x14 
-3.657078 -2.558799 -2.790860 -2.797736 -2.797736

> yall[3,10:14]
      y10       y11       y12       y13       y14  
-1.938531 -2.991856 -2.597014 -2.694228 -2.694228 

这本质上是一个随机游走问题。有没有一种方法可以让每个点都达到在[-3,3]之间然后一到就不走的目标?

我认为问题在于您的循环在索引 j(1 到 150)上 运行 并替换了 j+1 列中的值。因此,这些值可能会在循环的下一次迭代中被替换(取决于新的 j 和 j+1 值)。

列的创建和 checking/replacing 值的分离是否得到您想要的?如果两个值 (x/y) 在同一列中的范围内(我假设这就是您想要的),这会使值保持在范围内。

为了简化一些事情,我使用逻辑向量而不是行循环来有条件地替换值。

n <- 20
set.seed(4)
x0 <- runif(n = n, min = -9, max = 9)
set.seed(16)
y0 <- runif(n = n, min = -9, max = 9)

iter <- 150

for(j in 1:iter){
  St <- runif(n = n, min = 0, max = 2)
  dt <- runif(n = n, min = 0, max = 2*pi)
  dx <- cos(dt)
  dy <- sin(dt)
  xm <- St*dx
  ym <- St*dy
  x0 <- cbind(x0, xm)
  y0 <- cbind(y0, ym)
}

xall <- t(apply(x0, 1, cumsum))
yall <- t(apply(y0, 1, cumsum))

#function to check if values are in target range
chk <- function(x) {x <= 3 & x >= -3}

for(icol in 1:iter) {
  
  #condition1: values in column icol+1 between -3 and 3
  idx1 <- chk(xall[,icol+1]) &  chk(yall[,icol+1])

  #condition2: values in column icol between -3 and 3
  idx2 <- chk(xall[,icol]) &  chk(yall[,icol])

  #replace values in icol+1 with icol if condition 2 but not condition 1
  idx3 = !idx1 & idx2
  
  xall[idx3,icol+1] <- xall[idx3,icol]
  yall[idx3,icol+1] <- yall[idx3,icol]
  
}
xall[3,10:14]
       xm        xm        xm        xm        xm 
-3.657078 -2.558799 -2.790860 -2.797736 -2.797736 

yall[3,10:14]
       ym        ym        ym        ym        ym 
-1.938531 -2.991856 -2.597014 -2.694228 -2.694228