22
votes
$\begingroup$

Is there an easy way in R to create a linear regression over a model with 100 parameters in R? Let's say we have a vector Y with 10 values and a dataframe X with 10 columns and 100 rows In mathematical notation I would write Y = X[[1]] + X[[2]] + ... + X[[100]]. How do I write something similar in R syntax?

$\endgroup$
3
  • 1
    $\begingroup$ are there 100 or 1000? Also, you would normally have the columns be the variables and the rows be observations (it appears that is reversed here) $\endgroup$
    – Macro
    May 30, 2012 at 13:09
  • $\begingroup$ 100 the extra 0 was a typo $\endgroup$
    – Christian
    May 30, 2012 at 13:11
  • 2
    $\begingroup$ Really? Are you sure you want to do this? I'd be concerned about overfitting and correlation between linear combinations of the predictors. Not only that, with 100 predictors but only 10 observations, you have $p>n$ and linear regression isn't going to work at all. $\endgroup$ May 31, 2012 at 1:47

4 Answers 4

29
votes
$\begingroup$

Try this

df<-data.frame(y=rnorm(10),x1=rnorm(10),x2=rnorm(10))
lm(y~.,df)
$\endgroup$
2
  • 4
    $\begingroup$ And if you want, say, all second-order interactions, you can write y ~ . + .^2. And so on. $\endgroup$ Mar 12, 2015 at 14:46
  • 3
    $\begingroup$ And if you want only some of the second order interactions, something like y ~ . + .:x1 will get you the interactions of each variable (except x1) with x1. And so on; you get the idea. $\endgroup$ Mar 12, 2015 at 14:48
21
votes
$\begingroup$

Great answers!

I would add that by default, calling formula on a data.frame creates an additive formula to regress the first column onto the others.

So in the case of the answer of @danas.zuokas you can even do

lm(df)

which is interpreted correctly.

$\endgroup$
2
  • $\begingroup$ Still, this answer does not work if you want to mix in interaction terms. Yours does (+1). $\endgroup$
    – gui11aume
    May 30, 2012 at 13:36
  • 6
    $\begingroup$ I'm continually amazed at how overloaded most of R's operators are :) $\endgroup$
    – Macro
    May 30, 2012 at 13:38
19
votes
$\begingroup$

If each row is an observation and each column is a predictor so that $Y$ is an $n$-length vector and $X$ is an $n \times p$ matrix ($p=100$ in this case), then you can do this with

Z = as.data.frame(cbind(Y,X))
lm(Y ~ .,data=Z)

If there are other columns you did not want to include as predictors, you would have to remove them from X before using this trick, or using - in the model formula to exclude them. For example, if you wanted to exclude the 67th predictor (that has the corresponding name x67), then you could write

lm(Y ~ .-x67,data=Z)

Also, if you want to include interactions, etc.. you will need to add them manually as (for example)

lm(Y ~ .+X[,1]*X[,2],data=Z)

or make sure they are entered as columns of X.

$\endgroup$
19
votes
$\begingroup$

You can also use a combination of the formula and paste functions.

Setup data: Let's imagine we have a data.frame that contains the predictor variables x1 to x100 and our dependent variable y, but that there is also a nuisance variable asdfasdf. Also the predictor variables are arranged in an order such that they are not all contiguous in the data.frame.

Data <- data.frame(matrix(rnorm(102 * 200), ncol=102))
names(Data) <- c(paste("x", 1:50, sep=""), 
    "asdfasdf", "y", paste("x", 51:100, sep=""))

Imagine also that you have a string containing the names of the predictor variables. In this case, this can easily be created using the paste function, but in other situations, grep or some other approach might be used to get this string.

PredictorVariables <- paste("x", 1:100, sep="")

Apply approach: We can then construct a formula as follows:

Formula <- formula(paste("y ~ ", 
     paste(PredictorVariables, collapse=" + ")))
lm(Formula, Data)
  • the collapse argument inserts + between the predictor variables
  • formula converts the string into an object of class formula suitable for the lm function.

More generally, I use the following function quite regularly when I want to supply a the predictor variables as vector of variable names.

regression <- function(dv, ivs, data) {
    # run a linear model with text arguments for dv and ivs
    iv_string <- paste(ivs, collapse=" + ")
    regression_formula <- as.formula(paste(dv, iv_string, sep=" ~ "))
    lm(regression_formula, data)

}

E.g.,

regression("y", PredictorVariables, Data)
$\endgroup$
1
  • 2
    $\begingroup$ +1. I use this technique all the time. Occasionally, however, having the formula stored in a variable causes issues. See stackoverflow.com/a/7668846/210673 for use of do.call evaluate the formula before calling lm. $\endgroup$ May 31, 2012 at 1:44

Not the answer you're looking for? Browse other questions tagged or ask your own question.