在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 次。每次迭代和添加新列后,应遵循以下规则:
- 如果第j+1列的两个新值都在-3和3之间,无论如何都取新值,即使第j列的当前值也在范围内
- 如果第 j 列中至少有一个当前值超出此范围,无论如何都从第 j+1 列中获取新值
- 如果第j列中的当前值在范围内,但第j+1列中的新值不在范围内,则将第j+1列中的新值替换为第j列中的当前值
- 完成列值比较,生成新列,然后再次检查规则
我将在此处给出我的代码的示例输出,该代码目前无法正常工作:
> 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
我正在使用 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 次。每次迭代和添加新列后,应遵循以下规则:
- 如果第j+1列的两个新值都在-3和3之间,无论如何都取新值,即使第j列的当前值也在范围内
- 如果第 j 列中至少有一个当前值超出此范围,无论如何都从第 j+1 列中获取新值
- 如果第j列中的当前值在范围内,但第j+1列中的新值不在范围内,则将第j+1列中的新值替换为第j列中的当前值
- 完成列值比较,生成新列,然后再次检查规则
我将在此处给出我的代码的示例输出,该代码目前无法正常工作:
> 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