如何解决使用with更新函数中的列表不会返回更新的输出
如何在函数中使用with()
(或替代方法),以便在执行函数后更新并返回数据?我知道正在调用数据(在我的情况下,我想在每个时间步长更新的列表中的对象和为此执行的输入参数),正在执行for循环中的命令,但未在更新数据回。为什么会这样呢?我是否缺少有关with()
函数的内容?
我还尝试了within()
和within.list()
,它们在初始化时返回的输出与此列表相同。
#~ input parameters
xPRM <- list()
xPRM$n_ts <- 4
xPRM$n_yrs <- 1
xPRM$n_x1 <- 25
xPRM$n_x2 <- 10
xPRM$n_x3 <- 5
set.seed(1)
my_func <- function(X){
#~ lists to collect data after functions have been executed in each time-step
list1 <- vector(mode = "list",length = X$n_ts*X$n_yrs)
list2 <- vector(mode = "list",length = X$n_ts*X$n_yrs)
# etc.
#~ list for compartments (computations in each time step will be in these compartments)
comp.1 <- list()
comp.2 <- list()
# etc.
#~ comp.1 initialisation
comp.1$ts <- rep(0,X$n_x1)
comp.1$yr <- rep(0,X$n_x1)
comp.1$v1 <- rnorm(X$n_x1,X$n_x2,X$n_x3)
comp.1$v2 <- rep(0,X$n_x1)
with(c(comp.1,X),for(i in 1:n_ts*n_yrs){
ts <- i
yr <- ceiling(i/n_ts)
v1[v1 >= 5] <- v1[v1 >= 5]^(n_x3/i) #~ do something
v2[v1 >= 10] <- v2[v1 >= 10] + n_x3*i #~ do something again
#print(v2) #~ will show that the somethings are being done
#~Return data at end of time step
list1[[i]] <- comp.1
# list2[[i]] <- comp.2
# etc.
}
)
all_lists <- list(A = list1,B = list2
# etc.,)
all_lists
# list1
# comp.1
}
my_func(X = xPRM)
编辑
set.seed(1)
#~ lists to collect data after functions have been executed in each time-step
list1 <- vector(mode = "list",length = X$n_ts*X$n_yrs)
list2 <- vector(mode = "list",length = X$n_ts*X$n_yrs)
# etc.
#~ comp.1 initialisation
comp.1$ts <- rep(0,xPRM$n_x1)
comp.1$yr <- rep(0,xPRM$n_x1)
comp.1$v1 <- rnorm(xPRM$n_x1,xPRM$n_x2,xPRM$n_x3)
comp.1$v2 <- rep(0,xPRM$n_x1)
for(i in 1:xPRM$n_ts*xPRM$n_yrs){
comp.1$ts <- i
comp.1$yr <- ceiling(i/xPRM$n_ts)
comp.1$v1[comp.1$v1 >= 5] <- comp.1$v1[comp.1$v1 >= 5]^(xPRM$n_x3/i) #~ do something
comp.1$v2[comp.1$v1 >= 10] <- comp.1$v2[comp.1$v1 >= 10] + xPRM$n_x3*i #~ do something again
#~Return data at end of time step
list1[[i]] <- comp.1
# list2[[i]] <- comp.2
# etc.
}
all_lists <- list(A = list1,B = list2
# etc.,)
#~ Expected output
all_lists
解决方法
问题是base R
在调用时创建的本地环境中执行其所有操作,包括分配。这意味着df$check <- +( Reduce(`&`,lapply(split.default(replace(df[-1],is.na(df[-1]),0),sub("time_\\d+","",names(df)[-1])),function(x) !(x[[1]] & !x[[2]]))))
不会在with()
范围之外进行更新。
来自with()
docs:
with 是一种通用函数,用于在由数据构造的本地环境中评估expr。
...
请注意,expr中的分配发生在构造的环境中,而不是在用户的工作空间中。
...
对于交互式使用来说,这是非常有效的,而且阅读起来很不错。但是,对于编程(即,在一个人的函数中),需要格外小心,并且通常应避免使用with(),例如,数据中的变量可能会意外覆盖局部变量,请参见参考资料。
您可以坚持使用list1
赋值运算符在全局上下文中更新with()
。 (请注意,应谨慎使用这种强制全局分配-请参见讨论here。)
此外,list1
实际上并未在其自身的<<-
上下文中进行更新,因此您需要在完成计算后建立一个列表并将其存储在comp.1
中
赞:
with()
进行了这些更改后,list1[[i]]
实现的输出将与您的预期输出完全匹配。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。