【问题标题】:Quoting hell with formulas用公式引用地狱
【发布时间】:2018-05-11 20:06:49
【问题描述】:

我有一个需要重复执行的任务,所以我正在尝试为它编写一个函数。我的函数几乎完成了,除了一个缺陷:我不能将公式作为参数传递,除非它是字符串的形式。

library(lme4)
library(lazyeval)

get_pvals_qrhs <- function(df, cols, qrhs) {
    cols <- substitute(cols)
    col_pos <- setNames(as.list(seq_along(df)), names(df))
    pos <- eval(cols, col_pos)
    formulas <- lapply(pos, function(x) formula(paste(colnames(df[x]), "~", qrhs)))
    models <- lapply(formulas, lmer, data=df, REML=FALSE)
    tvals <- lapply(models, function(x) data.frame(coef(summary(x)))[c(2), ]$t.value)
    pvals <- lapply(tvals, function(x) { 2 * (1 - pnorm(abs(x))) })
    return(unlist(pvals))
}

works <- get_pvals_qrhs(iris, Sepal.Length:Sepal.Width, "Species + (1 + Petal.Length | Petal.Width)")
works

get_pvals_rhs <- function(df, cols, rhs) {
    cols <- substitute(cols)
    col_pos <- setNames(as.list(seq_along(df)), names(df))
    pos <- eval(cols, col_pos)
    formulas <- lapply(pos, function(x) formula(paste(colnames(df[x]), "~", quote(rhs))))
    models <- lapply(formulas, function(x) lmer, data=df, REML=FALSE)
    tvals <- lapply(models, function(x) data.frame(coef(summary(x)))[c(2), ]$t.value)
    pvals <- lapply(tvals, function(x) { 2 * (1 - pnorm(abs(x))) })
    return(unlist(pvals))
}

fails <- get_pvals_rhs(iris, Sepal.Length:Sepal.Width, Species + (1 + Petal.Length | Petal.Width))
fails

无论我对第二个函数中formulas &lt;- ... 行中的rhs 术语做什么,我都无法获得从第一个函数中获得的结果。我做错了什么?

【问题讨论】:

    标签: r


    【解决方案1】:

    你需要替换来获取表达式,然后你可以将它解析为一个字符串

    get_pvals_rhs <- function(df, cols, rhs) {
      cols <- substitute(cols)
      rhs <- deparse(substitute(rhs))
      col_pos <- setNames(as.list(seq_along(df)), names(df))
      pos <- eval(cols, col_pos)
      formulas <- lapply(pos, function(x) formula(paste(colnames(df[x]), "~", rhs)))
      models <- lapply(formulas, lmer, data=df, REML=FALSE)
      tvals <- lapply(models, function(x) data.frame(coef(summary(x)))[c(2), ]$t.value)
      pvals <- lapply(tvals, function(x) { 2 * (1 - pnorm(abs(x))) })
      return(unlist(pvals))
    }
    

    并经过测试

    get_pvals_rhs(iris, Sepal.Length:Sepal.Width, Species + (1 + Petal.Length | Petal.Width))
    

    但实际上,在使用公式部分时,通常最好总是在它们前面加上~,这样您就不必使用substitute(),并且可以使用update() 之类的函数来更轻松地更改公式。有点像

    get_pvals_rhs <- function(df, cols, rhs) {
      cols <- substitute(cols)
      col_pos <- setNames(as.list(seq_along(df)), names(df))
      pos <- eval(cols, col_pos)
      formulas <- lapply(colnames(df[pos]), function(x) update(rhs, reformulate(".", x)))
      models <- lapply(formulas, lmer, data=df, REML=FALSE)
      tvals <- lapply(models, function(x) data.frame(coef(summary(x)))[c(2), ]$t.value)
      pvals <- lapply(tvals, function(x) { 2 * (1 - pnorm(abs(x))) })
      return(unlist(pvals))
    }
    get_pvals_rhs(iris, Sepal.Length:Sepal.Width, ~ Species + (1 + Petal.Length | Petal.Width))
    

    【讨论】:

    • 叹气,编辑失败。我测试了你的两个建议,但都没有在这里工作。第一个返回:Error in FUN(X[[i]], ...) : unused arguments (data = list(Sepal.Length = c(5.1, 4.9, ,后跟更多数字。第二个返回了同样的东西。 :-(
    • @JackTwilley 您是否完全复制了我输入的内容?您在 lmer 的应用程序中也有错字/错误。
    • 我以为我完全复制了你放的东西。是在lmer 前面使用function(x) 你提到的错字吗?
    • 是的。这是防止向 lmer 填充 data 参数,这会导致未使用的参数错误。
    • 我现在想知道有多少deparse、substitute 和朋友的排列方式我曾尝试过使用function(x)。啊。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-01-13
    • 2016-08-30
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    相关资源
    最近更新 更多