【问题标题】:How can I avoid declaring a global variable in this R code?如何避免在此 R 代码中声明全局变量?
【发布时间】:2015-03-10 04:25:08
【问题描述】:

我正在尝试将 Kyle Gorman's autoloess 函数修改为可作为 ggplot2stat_smooth 中的方法调用。 autoloess 是一个简单的包装器,它通过优化器运行 loess 以找到最小化 AICc 的 span 的值。

我创建了一些可以成功运行的东西,但只能使用全局变量。有没有更优雅、更惯用的编程方式?

我的代码:

AICc.loess <- function(fit) {
  # compute AIC_C for a LOESS fit, from:
  # 
  # Hurvich, C.M., Simonoff, J.S., and Tsai, C. L. 1998. Smoothing 
  # parameter selection in nonparametric regression using an improved 
  # Akaike Information Criterion. Journal of the Royal Statistical 
  # Society B 60: 271–293.
  # 
  # @param fit        loess fit
  # @return           'aicc' value
  stopifnot(inherits(fit, 'loess'))
  # parameters
  n <- fit$n
  trace <- fit$trace.hat
  sigma2 <- sum(resid(fit) ^ 2) / (n - 1)
  return(log(sigma2) + 1 + 2 * (2 * (trace + 1)) / (n - trace - 2))
}


.autoloess.magic.w <- NULL
autoloess <- function(formula, data, weights, span=c(0.01, 2.0)) {
  .autoloess.magic.w <- ~weights
  fit <- loess(formula=formula, 
               data=data, 
               weights=.autoloess.magic.w)
  stopifnot(length(span) == 2)
  # loss function in form to be used by optimize
  f <- function(span) AICc.loess(update(fit, span=span))
  # find best loess according to loss function
  res <- update(fit, span=optimize(f, span)$minimum)
  cat(paste("Optimal span:", res$pars$span, "\n"))
  return(res)
}

还有一个快速测试:

# Test
library(ggplot2)
set.seed(1984)
# Create a cubic curve
df <- data.frame(x=1:2500, y=500000 +
                   (-1000*(1:2500)) +
                   ((1:2500)^2)  +
                   -0.00025*((1:2500)^3) +
                   rnorm(2500, sd=60000),
                 ww=runif(2500, min=0, max=10))
# Use loess span
ggplot(df, aes(x=x, y=y, weight=ww)) + geom_point() + stat_smooth(method="loess")

# Use autoloess
ggplot(df, aes(x=x, y=y, weight=ww)) + geom_point() +  stat_smooth(method="autoloess")

【问题讨论】:

    标签: r ggplot2 idioms


    【解决方案1】:

    您可以使用weight 变量(似乎在调用函数时它就在那里):

    autoloess <- function(formula, data, weights, span=c(0.01, 2.0)) {
    
      fit <- loess(formula = formula, 
                   data = data, 
                   weights=weight)
    
      stopifnot(length(span) == 2)
    
      # loss function in form to be used by optimize
      f <- function(span) AICc.loess(update(fit, span=span))
      # find best loess according to loss function
      res <- update(fit, span=optimize(f, span)$minimum)
      cat(paste("Optimal span:", res$pars$span, "\n"))
      return(res)
    }
    

    【讨论】:

    • 奇怪的是这行得通。现在不知道“权重”参数是怎么回事,但也许最好不要问!
    • 我认为在weights 中你得到一个评估为weight 的承诺(我不知道在哪个环境中)。直接使用weight 是一种捷径,但它可以工作......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 2013-09-25
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    相关资源
    最近更新 更多