Verbatim命令参数:包装器中的deparse(substitute(foo))

时间:2011-01-12 01:07:45

标签: r

对于那些熟练掌握R评估者如何处理函数调用的细节,这里有一点益智。假设我想编写一个带有R语句的函数,与我在命令行中编写的语句相同,并回显它和评估结果。例如:

 > p.eval(sum(1:3))
 sum(1:3) --> 6

这很容易;这是p.eval()

的定义
p.eval <- function(v,prefix="--> ") { 
   cmd <- deparse(substitute(v)); cat(cmd,prefix,v,"\n") 
}

但是假设我现在想要在p.eval周围编写一个包装器,以相同的方式调用;也许作为一个有点疯狂的二元运算符,带有一个虚拟的第二个参数:

%PE% <- function(x,...) p.eval(x)

我想像这样调用它:sum(1:3) %PE% 0应该等同于旧p.eval(sum(1:3))。当然,这不起作用,因为deparse(substitute())的{​​{1}}现在提供p.eval()

开明的问题:有没有办法按照我的意愿使这项工作?对于这种特殊用法,我通过复制/粘贴{的单行定义来定义x我很好{1}},所以这个问题主要是学术性的。也许我会了解R评估员的细节:)

PS:为什么可能会发现上述函数有用?假设我开发了一些分析代码并通过org-babel以非交互方式调用它(如果你是一个组织模式和/或,这绝对是值得玩的一个Emacs用户)。默认情况下,org-babel会在解释器中评估事物时啜饮输出。因此,如果我想获得除原始数字之外的任何内容,我必须明确构造要通过%PE%p.eval打印的字符串,但是当他们在分析中飞行时谁想要这样做?上面的hack允许您在想要打印的行之后简单地追加%PE%0,这会将命令回显到组织输出。

2 个答案:

答案 0 :(得分:11)

试试这个:

> "%PE%" <- function(x, ...) do.call(p.eval, list(substitute(x)))
> sum(1:3) %PE% 0
sum(1:3) -->  6 

答案 1 :(得分:1)

也可以让p.eval返回“v”然后:

 p.eval <- function(v,prefix="--> ") {
        cmd <- deparse(substitute(v)); cat(cmd,prefix,v,"\n") ; return(v)  } 
"%PE%" <- function(x, y=NULL) x 
 sum(1:3) %PE% Inf
 #[1] 6  
sum(1:3) %PE%   # won't accept single argument
  r   # give it anything
 #[1] 6