假设我有一个想要稍微调整行为的函数(比如跳过某一行).我可以

  1. 复制和粘贴函数并更改它(&A).
  2. 使用debug以交互方式更改代码.
  3. 使用trace注入自己的代码.

我对这个职位的 Select 3有百分之百的兴趣.

例如,让我们假设以下非常简单的代码:

f <- function(dbg) {
  x <- rnorm(1)
  if (dbg) {
     cat("Message 1\n")
  }
  if (x < 0 & dbg) {
     cat("Message 2\n")
  } 
  x
}

如果(无论出于什么原因)我想跳过Message 2(但保留Message 1),我可以使用trace,如下所示:

set.seed(12231)
untrace(f)
f(TRUE)
# Message 1
# Message 2
# [1] -0.5787277

trace(f, quote(dbg <- FALSE), at = 4, print = FALSE)
set.seed(12231)
f(TRUE)
# Message 1
# [1] -0.5787277

现在假设略有不同的函数g:

g <- function() {
  x <- rnorm(1)
  cat("Message\n")
  cat("Message 2\n")
  x
}

Conceptually我想做一些类似的事情:

trace(g, quote(if(FALSE)), at = 4, print = FALSE) 

但这显然行不通.

有没有办法用trace跳过(A)某些行?或者是我复制、粘贴和编辑该功能的唯一 Select ?

推荐答案

实际上,trace所做的(对于常规函数)是在函数体内的所需位置插入对.doTrace的调用.我们可以手动执行相同的操作,以达到完全相同的效果.

但在您的情况下,我们想要remove而不是加法;我们也可以这样做:

modified_body <- body(g)
modified_body[4] <- NULL

original_body <- body(g)
body(g) <- modified_body

g()

# “untrace”:
body(g) <- original_body

我试着让它与trace一起工作,通过传递修改后的Body作为tracer.不幸的是,我无法阻止原始函数随后执行:将显式return()调用添加到tracer不起任何作用(因为.doTrace使用eval.parent来计算tracer代码,而eval中的return不会退出调用范围).我用stop()代替return().然而,这是不可取的,因为它总是下降到top level而不是呼叫者g.我试图通过安装globalCallingHandler来影响这一点,但没有合适的重启可以调用,而且无论如何,定期重启会让我们直接回到g,而不是它的调用者.

即使在原则上,我也不知道这是否可以绕过:它本质上需要修改活动调用堆栈--它重新启动do,但据我所知仅以非常有限的方式(即,通过abort重新启动删除entire调用堆栈,或通过在最里面的调用帧内恢复).

R相关问答推荐

x[[1]]中的错误:脚注越界

Highcharter多次钻取不起作用,使用不同方法

在使用ggroove后,将图例合并在gplot中

单个轮廓重叠条的单独图例

如何在区分不同条件的同时可视化跨时间的连续变量?

使用外部文件分配变量名及其值

根据列A中的差异变异列,其中行由列B中的相对值标识

如何基于两个条件从一列中提取行

基于Key->Value数据帧的基因子集相关性提取

我如何go 掉盒子图底部的数字?

在R中使用列表(作为tibble列)进行向量化?

我是否可以使用多个变异项来构建顺序列(标记多个问题)

R -基线图-图形周围的阴影区域

如何为混合模型输出绘制不同的线型?

R:水平旋转图

R,将组ID分配给另一个观测ID变量中的值的组合

如果y中存在x中的值,则将y行中的多个值复制到相应的x行中

使用';IF';运算符判断数据框单元格中的给定值是否属于一组值

获取列位置

使用for()循环将数据处理应用于数据集的所有行