0

我已经定义了一个绑定函数,

b <- function(f,...) function(x) f(x, ...)

所以我可以做类似的事情(这是一个假的例子)

d = data.frame(x=c(1,2,1), y=c(10, 20, 5))
ddply(d, ~x, b(transform, y=sum(y)))

代替

ddply(d, ~x, function (df) { transform(df, y=sum(y)) }

现在,我正在尝试定义一个运算符

'%b%' <- function(x,...) b(x,...)

并尝试

ddply(d, ~x, transform %b% (z=y*10)))

它不起作用。有什么不同 ?

当我做

> b(transform, y=y/sum(y))(d)
x         y c.1..2..1.
1 1 0.2857143          1
2 2 0.5714286          2
3 1 0.1428571          1

这行得通,但是

> transform %b% (y=y/sum(y))(d)
Error in transform %b% (y = y/sum(y))(d) : object 'y' not found

我了解,存在“捕获”差异,我该怎么办?

4

1 回答 1

2

为了使您的示例工作,您需要将函数参数与现有函数匹配,使用match.fun()

`%b%` <- function(x,...) match.fun(b)(x,...)
ddply(d, ~x, transform %b% (z=y*10))

  x  y
1 1 10
2 1  5
3 2 20

match.fun()如果你在你的第一个定义中使用它也会更安全f

b <- function(f, ...) function(x) match.fun(f)(x, ...)
ddply(d, ~x, b(transform, y=sum(y)))
  x  y
1 1 10
2 1  5
3 2 20

回答了您的问题后,我现在必须指出,我不明白您为什么要这样做,因为plyrddply基础 R 函数这样的apply函数已经这样做了。

所以,我会像这样写你原来的例子:

ddply(d, ~x, transform, y=sum(y))
  x  y
1 1 15
2 1 15
3 2 20

ddply(d, ~x, transform, y=y/sum(y))
  x         y
1 1 0.6666667
2 1 0.3333333
3 2 1.0000000

编辑

我又看了你的问题。您只是在函数定义中犯了语法错误。这与中缀运算符完美配合:

'%b%' <- function(f,...) function(x) f(x, ...)
ddply(d, ~x, transform %b% (z=y*10))
  x  y
1 1 10
2 1  5
3 2 20
于 2012-06-26T11:18:12.160 回答