mathnoob123
mathnoob123

Reputation: 229

How to pass bunch of elements as an argument in R?

I am trying to pass an array in R as an argument such that specific elements can be called at specific locations. A sketch I have in mind is

labels = c("Direction","Lag1","Lag2",...,"Lagn")
model = function(DATA, elements,...){
   ....
   glm.fit = glm(elements[1]~elements[2]+....+elements[n+1], data=DATA)}

An example of required output is

labels = c("Direction","Lag1","Lag2","Lag3","Lag4")
model(file, labels) 
#^^^^ This should attempt to calculate 
#glm.fit = glm(Direction~Lag1+Lag2+Lag3+Lag4, data=file)

Now in this implementation, I am struggling through two problems.

1) The only way I can create an array containing features is if I keep them in string form. Whereas in the function I need them in variable form.

2) Since the length of labels is arbitrary (I plan to use the same model with different datasets and thus the length of the array will change), I need some mechanism in which the plusses in between can be written automatically (since the number of plusses present also depend on the length of labels)

Upvotes: 2

Views: 324

Answers (4)

Joris C.
Joris C.

Reputation: 6234

For (generalized) linear models with only marginal terms, this is also sufficient:

## mpg ~ cyl + am + gear
glm(mtcars[c("mpg", "cyl", "am", "gear")])
#> 
#> Call:  glm(formula = mtcars[c("mpg", "cyl", "am", "gear")])
#> 
#> Coefficients:
#> (Intercept)          cyl           am         gear  
#>      38.787       -2.555        3.890       -1.212  
#> 
#> Degrees of Freedom: 31 Total (i.e. Null);  28 Residual
#> Null Deviance:       1126 
#> Residual Deviance: 262.4     AIC: 168.1

## mpg ~ cyl
glm(mtcars[c("mpg", "cyl")])
#> 
#> Call:  glm(formula = mtcars[c("mpg", "cyl")])
#> 
#> Coefficients:
#> (Intercept)          cyl  
#>      37.885       -2.876  
#> 
#> Degrees of Freedom: 31 Total (i.e. Null);  30 Residual
#> Null Deviance:       1126 
#> Residual Deviance: 308.3     AIC: 169.3

Upvotes: 0

M.Viking
M.Viking

Reputation: 5398

The reformulate() function is what you need!

mylabels = c("Lag1","Lag2","Lag3","Lag4")
myresponse = "Direction"
reformulate(mylabels, myresponse)

Direction ~ Lag1 + Lag2 + Lag3 + Lag4

Upvotes: 2

Ronak Shah
Ronak Shah

Reputation: 388982

We can write a function to handle variable arguments

fun_model <- function(data, response, predictor, ...) {
   formula <- paste0(response, "~", paste0(c(predictor, c(...)), collapse = "+"))
   glm(as.formula(formula), data = data)
}

fun_model(mtcars, "mpg", "cyl", "am", "gear")


#Call:  glm(formula = as.formula(formula), data = data)

#Coefficients:
#(Intercept)          cyl           am         gear  
#     38.787       -2.555        3.890       -1.212  

#Degrees of Freedom: 31 Total (i.e. Null);  28 Residual
#Null Deviance:     1126 
#Residual Deviance: 262.4   AIC: 168.1

fun_model(mtcars, "mpg", "cyl")

#Call:  glm(formula = as.formula(formula), data = data)

#Coefficients:
#(Intercept)          cyl  
#     37.885       -2.876  

#Degrees of Freedom: 31 Total (i.e. Null);  30 Residual
#Null Deviance:     1126 
#Residual Deviance: 308.3   AIC: 169.3

Upvotes: 1

Grada Gukovic
Grada Gukovic

Reputation: 1253

Try creating the formula object for the linear model by pasting together the elements of elements yourself:

glm.fit = glm(as.formula(
              paste(elements[1], paste(elements[2:length(elements)], 
              collapse = "+"), sep =" ~ ")), data = DATA)

A working example:

data(iris)
labs <- names(iris)
glm(as.formula(paste(labs[1], paste(labs[2:length(labs)], collapse = "+"), sep =" ~ ")), data = iris)

Call:  glm(formula = as.formula(paste(labs[1], paste(labs[2:length(labs)], 
    collapse = "+"), sep = " ~ ")), data = iris)

Coefficients:
      (Intercept)        Sepal.Width       Petal.Length        Petal.Width  
           2.1713             0.4959             0.8292            -0.3152  
Speciesversicolor   Speciesvirginica  
          -0.7236            -1.0235  

Degrees of Freedom: 149 Total (i.e. Null);  144 Residual
Null Deviance:      102.2 
Residual Deviance: 13.56    AIC: 79.12

Upvotes: 1

Related Questions