将圆括号中的函数从变量传递到rollapply

时间:2016-03-07 12:33:52

标签: r function

您可以至少以两种不同的方式将函数(在此示例中为mean)传递给rollapply(请注意第二个示例中的圆括号),因为它显示为here

> sub.as.avg.1 <- rollapply(sub.as, width = 1,  by = 1,  FUN = mean,   align = "left")
> sub.as.avg.1 <- rollapply(sub.as, width = 1,  by = 1,  FUN = (mean), align = "left")

现在我想从变量传递函数。这个是有效的:

> fun
[1] "mean"
> r2 <- rollapply(sub.as, width = 1, by = 1, FUN = (fun), align = "left")
>

但这不是:

> fun
[1] "(mean)"
> r2 <- rollapply(sub.as, width = 1, by = 1, FUN = fun, align = "left")
Error in get(as.character(FUN), mode = "function", envir = envir) : 
  object '(mean)' of mode 'function' was not found

如何使这项工作?圆括号对rollapply意味着什么?它们是rollapply具体还是R是一般的东西?

修改 基于@DavidGo答案,我试过以下:

library(zoo)

sub.as <- c(1, 0.75, 0.9, 0.475, 0.925, 0.975, 1, 1, 0.525, 1, 0.2, 0.2, 
 0.2, 0.2, 0.15, 0.15, 0.15, 0.15, 0.15, 0.45, 0.875, 0.175, 0.15, 
 0.15, 0.15, 0.1, 0.1, 0.1, 0.1, 0.35, 1)

my.func <- function(x, fun){
  result.vec <- rollapply(x, width = 1, by = 1, FUN = fun, align = "left")
  result.vec
}

r1 <- my.func(sub.as, mean)
r2 <- my.func(sub.as, (mean))

但似乎我在两种情况下都使用(mean)

> sub.as - r1
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> sub.as - r2
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> identical(sub.as, r1)
[1] TRUE
> identical(sub.as, r2)
[1] TRUE

1 个答案:

答案 0 :(得分:0)

似乎你初始化这样的乐趣:fun = "(mean)"而在你提供的例子中它是一个闭包。如果你想坚持这个例子,你可以输入:

library(zoo)
sub.as <- c(1, 0.75, 0.9, 0.475, 0.925, 0.975, 1, 1, 0.525, 1, 0.2, 0.2, 
 0.2, 0.2, 0.15, 0.15, 0.15, 0.15, 0.15, 0.45, 0.875, 0.175, 0.15, 
 0.15, 0.15, 0.1, 0.1, 0.1, 0.1, 0.35, 1)
fun <- (mean) # or fun <- mean
r2 <- rollapply(sub.as, width = 1, by = 1, FUN = fun, align = "left")

否则你也可以像这样转换你的角色:

fun = eval(parse("(mean)")), align = "left")

无论你怎么做,rollapply都希望FUN成为一个闭包

修改 @Roland是正确的,因为函数(mean)不存在作为一个正确的函数,并且内部调用的函数rollmean不能直接传递给rollapply,你需要实现一个变通方法。我这样做了,这可能不是最优雅的方式,但它应该像你期望的那样工作:

library(zoo)
my.func <- function(x, fun){
  if (deparse(substitute(fun)) == "mean") {
    result.vec <- rollapply(x, width = 1, by = 1, FUN = mean, align = "left")
  }
  else{
    result.vec <- rollapply(x, width = 1, by = 1, FUN = fun, align = "left") 
  }
  return(result.vec)
}
sub.as <- c(1, 0.75, 0.9, 0.475, 0.925, 0.975, 1, 1, 0.525, 1, 0.2, 0.2, 
            0.2, 0.2, 0.15, 0.15, 0.15, 0.15, 0.15, 0.45, 0.875, 0.175, 0.15, 
            0.15, 0.15, 0.1, 0.1, 0.1, 0.1, 0.35, 1)
r1 <- my.func(sub.as, mean)
r2 <- my.func(sub.as, (mean))
r3 <- rollapply(sub.as, width = 1, by = 1, FUN = mean, align = "left")
r4 <- rollapply(sub.as, width = 1, by = 1, FUN = (mean), align = "left")
print(identical(r1,r2))
print(identical(r1,r3))
print(identical(r4,r2))