提问人:Fabou 提问时间:6/15/2023 更新时间:6/15/2023 访问量:61
R:函数的意外行为(可能是由于函数中公式对象的环境范围)
R: unexpected behaviour of function (probably due to environmental scope of formula object within function)
问:
虽然是 R 的长期用户,但我几乎没有用 R 编写复杂程序的经验。在我的第一次尝试中,我遇到了代码的意外行为。也就是说,如果我尝试运行一个我已经定义了自己的函数,一个围绕 gamlss 回归模型适配的包装器,该函数就会失败。逐行交互地运行函数中的代码就可以了。奇怪的是,一旦我以交互方式运行代码一次,该函数就会显示预期的行为。
这里有一个最小的可重现的例子:
首先,我加载所需的包
library(data.table)
library(gamlss)
我定义了我的包装器函数
fun.wrapper <- function(dt, cores){
all_vars <- colnames(dt)[colnames(dt) > "b"]
scope_vars <- all_vars[1:ceiling(length(all_vars)/2)]
formula_full <- as.formula(paste0("a ~ ", paste(all_vars, collapse = " + ")))
mod0 <- gamlss(formula = formula_full, data = dt, family = "NO", trace = FALSE)
droper <- drop1All(object = mod0, scope = scope_vars, print = FALSE, parallel = ifelse(cores>1, "multicore", "no"), ncpus = cores)
return(droper)
}
我初始化一个随机数据集
data <- data.table(
x = rbinom(size = 1, prob = 0.3, n = 10),
y = rbinom(size = 1, prob = 0.1, n = 10),
z = rbinom(size = 1, prob = 0.2, n = 10),
a = rnorm(n = 10)^2)
我将该函数应用于数据,但失败并出现错误
res_f1 <- fun.wrapper(dt = data, cores = 1)
如果我一行一行地从包装器运行代码,结果符合预期
dt <- data
cores <- 1
all_vars <- colnames(dt)[colnames(dt) > "b"]
scope_vars <- all_vars[1:ceiling(length(all_vars)/2)]
formula_full <- as.formula(paste0("a ~ ", paste(all_vars, collapse = " + ")))
mod0 <- gamlss(formula_full, data = dt, family = "NO", trace = FALSE)
res_i1 <- drop1All(object = mod0, scope = scope_vars, print = FALSE, parallel = ifelse(cores>1, "multicore", "no"), ncpus = cores)
完成此操作后,我也可以成功运行包装器函数
res_f2 <- fun.wrapper(dt = data, cores = 1)
我尝试了几次,主要是反复试验和错误驱动的尝试来解决这个问题。我阅读了有关词法范围和闭包的文章,因为我强烈假设上面的 drop1All 调用访问了错误的数据。我试图将各自的变量分配给全局环境并<<。这些都没有奏效。
因此,如果你们中的一个人能为我指出这个问题的解决方案,我将非常高兴。提前致谢。
sessionInfo()
R version 4.2.1 (2022-06-23)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.4 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=de_AT.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=de_AT.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=de_AT.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=de_AT.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] parallel splines stats graphics grDevices utils datasets
[8] methods base
other attached packages:
[1] gamlss_5.4-12 nlme_3.1-162 gamlss.dist_6.0-5 MASS_7.3-58
[5] gamlss.data_6.0-2 data.table_1.14.8
loaded via a namespace (and not attached):
[1] compiler_4.2.1 Matrix_1.5-3 survival_3.5-5 grid_4.2.1
[5] lattice_0.20-45
答: 暂无答案
评论