简体   繁体   中英

Passing function argument to formula

I'm trying to understand why

foo = function(d,y,x) {
    fit = with(d, lm(y ~ x))
}
foo(myData, Y, X)

won't work, where for instance

myData = data.frame(Y=rnorm(50), X=runif(50))

The bit that seems tricky to me is passing the arguments x and y to a formula, as in lm(y ~ x) .

@DMT's answer explains what's going on nicely.

Here are the hoops to jump through if you want things to work as you expect:

lmwrap <- function(d,y,x) {
    ys <- deparse(substitute(y))
    xs <- deparse(substitute(x))
    f <- reformulate(xs,response=ys)
    return(lm(f,data=d))
}
mydata <- data.frame(X=1:10,Y=rnorm(10))
lmwrap(mydata,Y, X)

Or it can be simplified a bit if you pass the column names as strings rather than symbols.

lmwrap <- function(d,y,x) {
    f <- reformulate(xs, response=ys)
    return(lm(f, data=d))
}
lmwrap(mydata, "Y", "X")

This approach will be a bit fragile, eg if you pass arguments through another function. Also, getting the "Call" part of the formula to read Y~X takes more trickery ...

Y and X are your column names, not variables. They wouldn't in this case, be arguments to your function unless you passed them in as strings and essentially call

lm(mydata[,"Y"]~ mydata[,"X"])

If you were to run ls() on your console, Y and X would most likely not be there, so the function won't work. Print both x and y prior to the fit = call, and you'll likely see NULLs, which won't fly in lm.

One way to do this in your form is the following

lmwrap<-function(df, yname, xname){
fit=lm(d[,yname] ~ d[,xname])
}

lmwrap(mydata,"Y", "X")

But you could just make the lm call like regular

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM