问题描述
我正在尝试编写一个函数,该函数生成由单位球体约束的随机游走,从而产生由向量给出的随机游走的最后一个位置。在试图找出我的函数在哪里中断时,我尝试像这样拼凑:
norm_vec <- function(x) sqrt(sum(x^2))
sphere_start_checker <- function() {
repeat {
start_loc <- runif(3,min = -1,max = 1)
if (norm_vec(start_loc) < 1) return(start_loc)
}
}
n <- 10
set.seed(1)
new_loc <- as.matrix(t(sphere_start_checker()))
temp_loc <- as.matrix(t(c(0,0)))
for(i in n) {
repeat {
temp_loc <- new_loc[i,] + runif(3,min = -.01,max = .01)
if (norm_vec(temp_loc) < 1) {
return(new_loc <- rbind(new_loc,temp_loc))
}
}
}
new_loc
但是,当我在 for 循环之外手动迭代代码时,一切正常。我认为这与 R 的范围规则有关,并且我尝试将 rbind 的结果分配给全局环境,但这不起作用。
最初,我尝试编写这样的函数:
randomwalk_sphere <- function(n,radius,stepmax) {
# initialize sphere bounds
sphere_radius <- as.double(radius)
# initialize random starting vector
# while loop that adds a random vector to our start_loc n times,repeating once boundary condition is met
loop <- 0
new_loc <- sphere_start_checker()
while(loop <= n) {
repeat {
temp_loc <- new_loc + runif(3,min = -stepmax,max = stepmax)
if (norm_vec(temp_loc) < sphere_radius) {
return(assign("new_loc",temp_loc,env = .GlobalEnv))
}
}
loop <- loop + 1
}
new_loc
}
但是当我这样做时,while 循环似乎不起作用,我只是从均匀分布而不是从随机游走中获取初始 new_loc 坐标。我意识到使用 rbind 可能是一种更正确的方法,但我有兴趣了解为什么这种方法不起作用。
解决方法
一些想法:
-
当您使用
for (i in n)
“修复”问题时,规范(更常见)方法通常是将n
保持为单长度计数,并使用 {{1} } 或seq_len(n)
调用中的类似内容,例如for
。 -
n <- 10; for (i in seq_len(n))
在正式的return
声明之外的任何内容中都是不正确的;如果您想停止function(.){..}
,请使用repeat
。如此处所示,重新分配的范围不正确,因此break
从未真正与所有迭代结果重新分配。
最终,一旦您停止尝试从非函数中 new_loc
,它就会起作用。
return