代码之家  ›  专栏  ›  技术社区  ›  tjebo

闭包r中lm的参数

r
  •  2
  • tjebo  · 技术社区  · 7 年前

    考虑以下功能:

    lm_eqn <- function(df, indep, dep){
      
      lm(formula = dep ~ indep, data = df)
    }
    
    lm_eqn(iris, Sepal.Length, Sepal.Width)  ## does not work, throws error. 
    

    我试着用几种方法引用/取消引用。没有一个是成功的,抛出不同的错误,也没有一个对我有帮助:

    deparse(substitute(dep))

    中的错误 contrasts<- ( *tmp* 对比度只能应用于具有2个或更多级别的因子

    quo(dep) enquo(dep) expr(dep)

    在上面加上不带引号的Using !! :

    出错!dep:参数类型无效

    lm_eqn2 <- function(df){
      
         lm(formula = Sepal.Length ~ Sepal.Width, data = df)
    }
    
    lm_eqn2(iris)
    
    # Call:
    # lm(formula = Sepal.Length ~ Sepal.Width, data = df)
    
    # Coefficients:
    # (Intercept)  Sepal.Width  
    #     6.5262      -0.2234 
    

    4 回复  |  直到 5 年前
        1
  •  3
  •   bobbel    7 年前

    您可以引用输入,然后使用 eval(as.name()) 函数内部。

    lm_eqn <- function(df, indep, dep){
    
      lm(formula = eval(as.name(dep)) ~ eval(as.name(indep)), data = df)
    }
    
    lm_eqn(iris, 'Sepal.Length', 'Sepal.Width')
    
        2
  •  3
  •   Rui Barradas    7 年前

    可以使用带引号和不带引号的列名 substitute 从函数的源头上采取的技巧 library ,它也接受两者。

    lm_eqn <- function(df, indep, dep){
      indep <- as.character(substitute(indep))
      dep <- as.character(substitute(dep))
      fmla <- as.formula(paste(dep, indep, sep = "~"))
      lm(fmla, data = df)
    }
    
    lm_eqn(iris, 'Sepal.Length', 'Sepal.Width')
    #
    #Call:
    #lm(formula = fmla, data = df)
    #
    #Coefficients:
    # (Intercept)  Sepal.Length  
    #     3.41895      -0.06188  
    #
    
    lm_eqn(iris, Sepal.Length, Sepal.Width)
    #
    #Call:
    #lm(formula = fmla, data = df)
    #
    #Coefficients:
    # (Intercept)  Sepal.Length  
    #     3.41895      -0.06188  
    #
    
        3
  •  3
  •   Roman    7 年前

    不带引号的方法:

    > lm_eqn(iris, Sepal.Length, Sepal.Width)
    
    Call:
    lm(formula = dep ~ indep, data = df_lm)
    
    Coefficients:
    (Intercept)        indep  
        3.41895     -0.06188  
    

    警告 :传递不带引号的对象名在视觉上是令人愉快的,但通常是不赞成的,因为 可以

    代码

    lm_eqn <- function(df_lm, indep, dep){
        df_lm <- eval(as.name(deparse(substitute(df_lm))))
        indep <- df_lm[, grep(deparse(substitute(indep)), colnames(df_lm))]
        dep <- df_lm[, grep(deparse(substitute(dep)), colnames(df_lm))]
    
        lm(formula = dep ~ indep, data = df_lm)
    }
    
        4
  •  3
  •   alistaire    7 年前

    如果您想保持输出中的公式美观,可以调用 substitute 在整个调用中,它将插入变量名,然后调用 eval 在运行结果上:

    lm_eqn <- function(data, x, y){
        eval(substitute(
            lm(formula = y ~ x, data = data)
        ))
    }
    
    lm_eqn(iris, Sepal.Width, Sepal.Length)
    #> 
    #> Call:
    #> lm(formula = Sepal.Length ~ Sepal.Width, data = iris)    # <- pretty!
    #> 
    #> Coefficients:
    #> (Intercept)  Sepal.Width  
    #>      6.5262      -0.2234
    

    或者,为了让这一切变得简单(而且更加灵活),只需直接传递一个公式:

    lm_frm <- function(data, formula){
        lm(formula, data)
    }
    
    lm_frm(iris, Sepal.Length ~ Sepal.Width)
    #> 
    #> Call:
    #> lm(formula = formula, data = data)
    #> 
    #> Coefficients:
    #> (Intercept)  Sepal.Width  
    #>      6.5262      -0.2234
    

    包装 lm 呼叫 eval(substitute(...)) 也将用这种方法修复存储的调用结构。