Arguments for lm in closure r

lm function in r explained
lm.fit r
meaning of lm in r
basic lm in r
r lm offset
r lm order of variables
lm in r significance
lm in r dependent variable

I am clearly missing some understanding here of evaluation/ environments (I have the suspicion that the latter is the issue here).

Consider the following closure:

lm_eqn <- function(df, indep, dep){

  lm(formula = dep ~ indep, data = df)
}

lm_eqn(iris, Sepal.Length, Sepal.Width)  ## does not work, throws error. 

I tried to quote/unquote in several ways. None of those were succesful, throwing different errors and none of them were exactly helpful for me:

Using deparse(substitute(dep))

Error in contrasts<-(*tmp*, value = contr.funs[1 + isOF[nn]]) : contrasts can be applied only to factors with 2 or more levels

Using quo(dep) or enquo(dep) or expr(dep)

Error in model.frame.default(formula = dep ~ indep, data = df, drop.unused.levels = TRUE) : object is not a matrix

Using above with unquoting using !!:

Error in !dep : invalid argument type

Specifying the variable names for the formula within the function body works:

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 

What am I missing?

You can quote the input, and then use eval(as.name()) inside the function.

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')

R Tip: How to Pass a formula to lm – Win-Vector Blog, In addition, as is so often the case in R , there is already a known (f), data = mtcars) )) print(model) # Call: # lm(formula = mpg ~ cyl + disp + hp  Argument Matching Description. match (also known as a ‘closure’): An alternative is to explicitly select the arguments to be passed on, as is done in lm.

You can use both quoted and unquoted column names with the following substitute trick taken from the source of function library, which also accepts both.

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  
#

Programming Over lm() in R – Win-Vector Blog, For everything except the weights this is easy, as the linear regression function lm() is willing to take strings in its first argument “ formula ” (and  Using closures as objects in R For more and more clients we have been using a nice coding pattern taught to us by Garrett Grolemund in his book Hands-On Programming with R : make a function that returns a list of functions.

Approach without quotes:

> lm_eqn(iris, Sepal.Length, Sepal.Width)

Call:
lm(formula = dep ~ indep, data = df_lm)

Coefficients:
(Intercept)        indep  
    3.41895     -0.06188  

Caveat: Passing object names without quotes is visually pleasant, but generally frowned upon because it can introduce instability.

Code
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)
}

object of type 'closure' is not(?) subsettable, A common error in R is object of type 'closure' is not subsettable . Using subset syntax to manipulate formal arguments of functions. Here I provide some brief examples of how R programmers can utilize lexical closures to encapsulate both data and methods. To begin with a simple example, suppose you want a function that adds 2 to its argument.

If you want to keep the formula in the output pretty, you can call substitute on the whole call, which will interpolate the variable names, then call eval on the result to run it:

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

Or to make it all really simple (and a lot more flexible), just pass a formula directly:

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

Wrapping the lm call in eval(substitute(...)) will fix the stored call structure with this approach, too.

3 Efficient programming, Many people who use R would not describe themselves as “programmers”. Hence, the first few lines of a function typically perform argument checking. i.e. out = regression_plot(x, y) the variable out contains the output of the lm() call. A closure in R is an object that contains functions bound to the environment the  Stack Exchange network consists of 176 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

lm function, additional arguments to be passed to the low level regression fitting functions (​see below). Details. Models for lm are specified symbolically. A typical model has​  The formal arguments are the arguments included in the function de nition The formals function returns a list of all the formal arguments of a function Not every function call in R makes use of all the formal arguments Function arguments can be missing or might have default values. The R Language. Argument Matching.

[PDF] Introduction to the R Language - Functions, R functions arguments can be matched positionally or by name. So args(lm) function (formula, data, subset, weights, na.action, method = "qr", model = TRUE, x = FALSE, A function + an environment = a closure or function closure. The R​  Arguments x. An lm object created by stats::lm(). data. A data.frame() or tibble::tibble() containing the original data that was used to produce the object x. Defaults to stats::model.frame(x) so that augment(my_fit) returns the augmented original data. Do not pass new data to the data argument.

4 Linear Models - GR's Website, The first argument to lm() is a model formula, which has the response on the left of the One thing you can do with lmfit , as you can with any R object, is print it. i wrote a multilinear regression model this way m51 <- lm( voting.in.2017.National.elections ~ e.po.15,e.po.16,e.po.17,e.po.18,e.po.19,e.po.20,e.po.21,e.po.22,e.po.23

Comments
  • this looks very good. am on my way will have a look very soon. already many thanks
  • Thanks! That's a neat trick! I will however accept @bobbel's answer because they answered earlier and also have less rep
  • Thanks for your thoughts and also very interesting. I admit I prefer the other solutions though ;)