【问题标题】:Correctly referencing a formula using cast from reshape package使用 reshape 包中的 cast 正确引用公式
【发布时间】:2014-03-01 03:46:57
【问题描述】:

我正在尝试在 reshape 包中的“cast”函数周围包装一个函数,该函数在转换之前对我的数据进行一些检查。

cast2 <- function(data, formula = ... ~ variable, fun.aggregate = NULL, 
        ..., margins = FALSE, subset = TRUE, df = FALSE, fill = NULL, 
        add.missing = FALSE, value = guess_value(data)) {

    #RunChecksOnData()

    return(cast(data, formula = formula, fun.aggregate = fun.aggregate, ..., margins = margins, subset = subset, df = df, fill = fill, add.missing = add.missing, value = value))
}

如果没有检查,我希望这个函数 'cast2' 会返回与 cast 相同的结果。 但是,当我采用其中一个特色示例时

names(airquality) <- tolower(names(airquality))
aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE)

然后运行:

cast2(aqm, day ~ month, mean, subset=variable=="ozone")

这会导致错误“eval(expr, envir, enclos) 中的错误:找不到对象‘变量’”

我怀疑这与公式通过函数的方式有关,但我无法弄清楚。 (我意识到我可以通过在 cast2 中复制所有 cast 函数代码来从技术上解决这个问题,但我确信一定有更简洁的方法。

【问题讨论】:

    标签: r casting reshape


    【解决方案1】:

    cast 已过时。你应该使用reshape2 而不是reshape,你有两个功能:dcastacast。实现您想要的一个想法是使用来自plyr. 这是一个示例:

    library(plyr)
    library(reshape2)
    dcast2 <- function(){
      names(airquality) <- tolower(names(airquality))
      aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE)
      dcast(aqm, variable ~ month, mean, subset = subset)
    }
    

    那你这样称呼它:

    dcast2(.(variable=="ozone"))
      variable        5        6        7        8        9
    1    ozone 23.61538 29.44444 59.11538 59.96154 31.44828
    

    【讨论】:

    • 谢谢!不幸的是,我现在需要继续使用旧版本的 R (2.13),所以我不能使用 reshape2。没有其他选择吗?我想仍然有可能通过正确传递公式变量来解决问题。
    【解决方案2】:

    您现在的问题是您无法评估 subset 参数,因为 cast 没有使用标准评估来捕获它。通过使用match.call(),您可以避免评估subset。错误中引用的variable 来自表达式subset=variable=="ozone"

    这里有一个解决方案。如果您真的只是要检查数据而不尝试修改它,那么这是微不足道的。您需要做的就是检查您的变量,如果没问题,将调用更改为cast 并进行评估。如果您需要修改变量,那么它有点棘手,但不是那么多。您需要确保调用引用了函数环境中修改后的变量。我在下面这样做:

    cast2 <- function(data, formula = ... ~ variable, fun.aggregate = NULL, 
                      margins = FALSE, subset = TRUE, df = FALSE, fill = NULL, 
                      add.missing = FALSE, value = guess_value(data)) {
    
      #RunChecksOnData()
      cast.call <- match.call()
      cast.call[[1]] <- quote(cast)       # update call
      data$value <- data$value * 100      # modify data
      cast.call[["data"]] <- quote(data)  # update call for modified data (otherwise this refers to aqm)
      eval(cast.call)
    }
    

    编辑:如果你确实使用它,你需要小心避免你的函数环境和生成调用的环境之间的冲突。只要您的函数不包含与调用中引用的任何变量同名的任何变量,这里就可以工作。如果您不能保证确实如此,那么您需要注意如何进行评估。我将为父函数的 parent.frame 创建一个新环境,在那里分配修改后的对象(例如data),然后在该环境中评估cast.call。仅当您需要修改参数时,此复杂性才适用。如果只需要检查参数,可以将最后一行修改为eval(cast.call, parent.frame()),应该没问题。

    【讨论】:

      猜你喜欢
      • 2012-06-19
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 2012-06-06
      • 1970-01-01
      相关资源
      最近更新 更多