在函数内打印或显示变量

20

在函数内部有没有一种方法可以打印或显示变量的值,而不是在调用函数后在函数外部打印变量的值?

我几乎肯定有这样的方法,而且认为这个代码被称为reveal或类似的名称,但我无法回忆出正确的术语。

my.function <- function(x) {

  y <- x^2
 #  reveal(y)
 #  display(y)

 # desired result is to print or display here:
 # [1] 16

  cat(y)
  print(y)
  return(y)  
}

x <- 4

my.function(x)
#16[1] 16
#[1] 16

cat(y)print(y)return(y)都是在函数外打印。感谢任何建议。

编辑

我在这里找到了一个类似的问题:

https://stat.ethz.ch/pipermail/r-help/2002-November/027348.html

Peter Dalgaard对该问题的回复是取消Misc选项卡下的buffered output选项。但是,在我的情况下,这似乎不起作用。也许这些问题没有关联。


1
我很困惑。你的意思是他们在函数外面打印吗?这是不可能的,因为4甚至还没有被传递到函数中... - Robert Krzyzanowski
} 后面出现了数字 16。 - Mark Miller
你能解释一下你的理由吗?我们肯定是以某种方式误解了你的意愿... - jbaums
2
看一下?debug,它将逐步执行函数并允许您在函数执行的不同点检查对象。要尝试,请使用debug(my.function); my.function(4),然后在定义之后且调用return之前的任何时候输入y - jbaums
2
你也可以尝试使用 message,它在“函数内部打印”方面表现良好——我也用它来调试并行操作。 - Gary Weissman
显示剩余5条评论
3个回答

29

我喜欢使用message函数进行调试打印,因为它似乎可以从任何深处发出的地方到达控制台。例如:

somefunc <- function(x) {
       message(paste('ok made it this far with x=',x))
       # some stuff to debug
       message(paste('ok made it this far with x^2=',x^2))
       # some more stuff to debug
       message(paste('ok made it to the end of the function with x^3=',x^3))
}

1
不错的函数!我在一个prettyNum()周围包装了一个print(),控制台返回了0.0001000000000001。将print()更改为message()给了我想要的0.0001。在某些情况下,print()似乎会忽略prettyNum(),不确定它是怎么回事... - PatrickT

21

您可以在函数内部放置print()调用(或者cat()调用),如果执行达到了该点,那么即使稍后发生错误,控制台也会产生输出。(如果您使用的IDE设置为“缓冲输出”,则可能需要使用flush.console())。

 > myf <- function(x){ print(x); y <- x^2; print(y); error() }
> myf(4)
[1] 4
[1] 16
Error in myf(4) : could not find function "error"

使用 browser() 函数作为调试路由更加优雅。通过更改 options() 来设置其操作:

> options(error=recover)
> myf(4)
[1] 4
[1] 16
Error in myf(4) : could not find function "error"

Enter a frame number, or 0 to exit   

1: myf(4)

Selection: 1
Called from: top level 
Browse[1]> x
[1] 4
Browse[1]> y
[1] 16
Browse[1]>    # hit a <return> to exit the browser 

Enter a frame number, or 0 to exit   

1: myf(4)

Selection: 0   # returns you to the console

非常好。浏览器功能和调试功能的清晰示例非常有价值。如果可以的话,我会点赞两次。 - Mark Miller

8
当我提出这个问题时,我可能在想show函数,它允许您查看变量的值,而不需要在return语句中包含该变量。但是,show命令会在函数外打印值。
my.function <- function(x) {
     y <- x^2
     show(y)
     show(length(y))
     z <- y + x
     return(z)
}

x <- 1:10

my.function(x)

 # [1]   1   4   9  16  25  36  49  64  81 100
 # [1] 10
 # [1]   2   6  12  20  30  42  56  72  90 110

编辑:2021年3月19日

从函数内部查看结果的另一种方式是将对象发送到全局变量。这可能有助于定位函数内的错误。

my.function <- function(x) {
     y <- x^2
     y <<- y
     z <- y + x
     z <<- z
     return(z)
}
y
#[1]   1   4   9  16  25  36  49  64  81 100
z
#[1]   2   6  12  20  30  42  56  72  90 110
x <- 1:10
my.function(x)
#[1]   2   6  12  20  30  42  56  72  90 110

1
show 函数不一定会返回一个值。它将显示 S4 对象的 show 函数定义的结果。对于没有特定 show 方法定义的类的 S4 对象,它调用 showDefault 并输出有关其类的消息,然后迭代插槽。对于基本或 S3 类的普通对象,它只调用 print。我认为如果对象是列表(如 cat),这样做更安全,以免出现错误。 - IRTFM
我认为 <<- 并不一定会在全局环境中进行赋值。相反,我认为它会在调用环境中进行赋值,这可能是全局环境,也可能不是。然而,当我查看帮助页面时,发现它会“通过父环境搜索已存在的变量定义,如果找到这样的变量(且其绑定未被锁定),则重新定义其值,否则在全局环境中进行赋值。” - IRTFM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接