【问题标题】:R: On scoping, passing arguments to interior functions, andR:关于作用域,将参数传递给内部函数,以及
【发布时间】:2018-09-06 14:28:16
【问题描述】:

下面的示例是我不断寻求更好地预测 R 将做什么的另一个实例。尽管已经多次阅读了有关匹配和范围界定的材料,但我仍然难以传递变量,而且很明显,要么我缺少其他规则,要么我误解了我所拥有的一些规则,据说,学习了。

这里ff() 调用了gg() 四次。这些调用的输出如下。这里实例 1 和 2 证实了我的期望。他们在ff的执行环境中找到aa,在gg的函数定义的封闭环境中找到cc。但是实例 2 和实例 3 让我感到惊讶。对于 3,我不确定会发生什么,因为我对通过 ... 传递的变量是否保留其名称仍然有些模糊。如果没有,我认为垃圾收集器可能会得到它。但我真的希望 4 将一个名为 cc 的变量传递给函数,其值为 13,但事实并非如此。

我原来的gg() 没有ls()list2env()。当我添加ls() 时,似乎表明... 传递了一个... 对象,其中cc 无法访问到函数体中cc 的范围。请注意,在我添加 all.names=TRUE 之前,ls() 不会显示 ...。然后我添加了 list2env(),条件是... 中有一些东西。但据我所知,这根本没有任何作用。

那么,三个问题:

  1. list2env 怎么了?为什么这里没有效果?
  2. 如何生成命名参数(在参数的意义上 按标签分配名称)中的... 通常在 就好像这个名字是正式的一样?
  3. 与 (2) 相同的问题,但针对具有 名称,或者是一个名称,没有通过标签中的标签分配该名称 参数列表。

aa <- 2
bb <- 3
cc <- 11
gg <- function(X, ...){
  if(length(alist(...)) > 1){list2env(alist(...), envir = parent.frame())} 
  env_vars <- ls(all.names=TRUE)
  out <-  cc * X
  print(env_vars)
  cat(X, ",  out = ", out, "\n", sep="")
}

ff <- function(){
  aa <- 5
  bb <- 7
  cc <- 13

  gg(aa)        \# 1
  gg(X=aa)      \# 2
  gg(aa, cc)    \# 3
  gg(aa, cc=cc) \# 4
}

ff()

[1] "..." "X"  
5,  out = 55
[1] "..." "X"  
5,  out = 55
[1] "..." "X"  
5,  out = 55
[1] "..." "X"  
5,  out = 55

非常感谢!给修复我格式的人。

【问题讨论】:

标签: r scope parameter-passing


【解决方案1】:

这看起来确实很奇怪,但经过反复试验我们发现

L <- list(...)
list2env(L, environment())

如果实际参数被命名,则将... 变量注入当前环境。看来创建一个中间变量来保存列表很重要,这里是L

如果实际参数被命名,通常可以像这样使用with

g <- function(X, ...) with(list(...), {
   print(ls())
})
g(1, cc = 2)
## [1] "cc"

【讨论】:

  • 您似乎在我编辑问题时回答了我的问题。你很快!但也许你可以看看第 3 个新问题?
  • 一个实际参数可以是一个表达式,因此您不能假设每个实际参数都有一个名称。正如评论者指出的那样,match.call() 可用于返回表示调用的语言对象以及用作其实际参数的表达式。
  • 我真的不希望通过...传递无名的参数,因为一旦进入体内,似乎很难告诉他们去哪里。您必须将它们全部匹配,这有悖于目的——如果您知道顺序,为什么不只添加形式。但我想知道如何使用 ... 传递 xx、xx=2 或 xx=. 形式的主体参数
  • 我刚刚用我上次评论中的所有三种参数类型尝试了你的“with”构造。基于 ls(),它适用于 xx=2 参数和 xx= 参数,但不适用于普通 xx 参数。但我不确定这是一个公平的测试,并且会进一步试验。
  • 我试图让 with(..., ) 使用具有名称但未“命名”的变量,即标记,我尝试提供 <...> xx = get("xx", envir=parent.frame())。我想在调用环境中使用 xx,而不是封闭环境。函数定义的 - 就像实际 arg 的名称一样。它不适用于该目的; body 中的 xx 在函数的封闭环境中找到 xx。而不是它的调用环境。 ——不知道为什么。我一直希望找到类似或并行的方式来处理命名(即标记)变量和带有名称的变量。也许我只需要克服它。
猜你喜欢
  • 2018-09-26
  • 2015-02-17
  • 2016-02-24
  • 2021-09-21
  • 1970-01-01
  • 2015-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多