6

问题的标题几乎说明了这一点:R 函数有没有办法找出它是直接调用还是从fororwhile循环内部调用?sys.frame(0)parent.frame(1)返回.GlobalEnv该函数是直接调用还是从这些循环之一中调用。那么,还有其他方法吗?

谢谢。

4

4 回答 4

2

这不是一个确定的答案,但我认为您的解决方案是sys.status查看sys.parents. 第二个示例适用于在另一个函数中和循环中调用该函数的情况。在不明确知道的情况下不确定如何区分这一点。

test <- function() sys.status()

for(i in 1:2){
  print(test())
 }


## $sys.calls
## $sys.calls[[1]]
## print(test())
## 
## $sys.calls[[2]]
## test()
## 
## $sys.calls[[3]]
## sys.status()
## 
##
## $sys.parents
## [1] 0 0 2
##
## $sys.frames
## $sys.frames[[1]]
## <environment: 0x0479a1c8>
##
## $sys.frames[[2]]
## <environment: 0x0479a2fc>
##
## $sys.frames[[3]]
## <environment: 0x0479a334>
##
##
## $sys.calls
## $sys.calls[[1]]
## print(test())
##
## $sys.calls[[2]]
## test()
## 
## $sys.calls[[3]]
## sys.status()
##
##
## $sys.parents
## [1] 0 0 2
## 
## $sys.frames
## $sys.frames[[1]]
## <environment: 0x047993cc>
## 
## $sys.frames[[2]]
## <environment: 0x04799570>

## $sys.frames[[3]]
## <environment: 0x047995a8>

test()

## $sys.calls
## $sys.calls[[1]]
## test()
## 
## $sys.calls[[2]]
## sys.status()
## 
## 
## $sys.parents
## [1] 0 1
## 
## $sys.frames
## $sys.frames[[1]]
## <environment: 0x04775500>
##   
##   $sys.frames[[2]]
## <environment: 0x04775538>

test_sq <- function() test()

for(i in 1:2){
  print(test_sq())
 }

## $sys.calls
## $sys.calls[[1]]
## print(test_sq())
## 
## $sys.calls[[2]]
## test_sq()
## 
## $sys.calls[[3]]
## test()
## 
## $sys.calls[[4]]
## sys.status()
## 
## 
## $sys.parents
## [1] 0 0 2 3
## 
## $sys.frames
## $sys.frames[[1]]
## <environment: 0x04766c60>
##   
##   $sys.frames[[2]]
## <environment: 0x04766dcc>
##   
##   $sys.frames[[3]]
## <environment: 0x04766e04>
##   
##   $sys.frames[[4]]
## <environment: 0x04766e3c>
##   
##   
##   $sys.calls
## $sys.calls[[1]]
## print(test_sq())
## 
## $sys.calls[[2]]
## test_sq()
## 
## $sys.calls[[3]]
## test()
## 
## $sys.calls[[4]]
## sys.status()
## 
## 
## $sys.parents
## [1] 0 0 2 3
## 
## $sys.frames
## $sys.frames[[1]]
## <environment: 0x04765ac8>
##   
##   $sys.frames[[2]]
## <environment: 0x04765c34>
##   
##   $sys.frames[[3]]
## <environment: 0x04765c6c>
##   
##   $sys.frames[[4]]
## <environment: 0x04765d30>

test_sq()


## $sys.calls
## $sys.calls[[1]]
## test_sq()
## 
## $sys.calls[[2]]
## test()
## 
## $sys.calls[[3]]
## sys.status()
## 
## 
## $sys.parents
## [1] 0 1 2
## 
## $sys.frames
## $sys.frames[[1]]
## <environment: 0x0475ce40>
##   
##   $sys.frames[[2]]
## <environment: 0x0475cee8>
##   
##   $sys.frames[[3]]
## <environment: 0x0475cf20>
于 2012-08-06T01:59:27.563 回答
2

不幸的是for没有sys.calls正常出现。虽然它有点 hack,但您实际上可以 override for,使其被包含在内:

`for` = function(iter, vec, expr) eval.parent(replace(sys.call(), 1, list(.Primitive('for'))))
in.for = function() '`for`' %in% lapply(sys.calls(), `[[`, 1)
my.fun = function() { print('before'); print(in.for()); print('after') }

my.fun()
# [1] "before"
# [1] FALSE
# [1] "after"
for (x in 1) my.fun()
# [1] "before"
# [1] TRUE
# [1] "after"
于 2012-08-07T00:46:52.977 回答
0

例如,您为什么不只使用可选参数

Blah <- function(Param1, OptionalParam = 0){
    if(OptionalParam == 1){
        #Do This
    }else{
        #Do this
    }
    #Everything Else
}
于 2012-08-06T01:36:02.253 回答
0

哎呀,那还为时过早。事实证明,索引变量在循环后确实存在。for()该死。

唔!我可能有它。我已经有一个函数可以用变量的内容替换函数中的任意字符串:

replaceincall <- function(xx,from,to){
  # from is a string, to is a name
  if(is.name(xx)){
    ifelse(as.character(xx)==from,return(to),return(xx));
  } else {
    if(is.call(xx)) {
      oo <- lapply(as.list(xx),function(yy) replaceincall(yy,from,to));
      return(as.call(oo));
    } else {
      return(xx);
    }
  }
}

在我的重载<<-函数中,我还已经从中提取了sys.call()与函数不对应的名称列表。这意味着它们是某种变量。我所要做的就是找到那些不在其中的ls(.GlobalEnv)那些,那些必须是索引变量,应该用它们在日志条目中的值替换(使用上面的函数)

现在,这可能会捕获并替换循环之外的东西......但这也许是一件好事,因为无论变量不在的原因如何.GlobalEnv,它仍然是一个动态变量,因此有一天当我查看日志时,我如果我现在不捕捉它的价值,我会想知道如何重建它。

有人认为这种推理有任何缺陷吗?

于 2012-08-06T02:28:08.257 回答