**Putting variable names into a model automatically (created 2010-09-20, updated 2011-12-02)**.

This page is moving to a new website.

I always have trouble with including a changing variable name into a sequence of statistical models in R, so when someone wrote about it on the R-Help list, I thought I should try some of the suggestions and then write them down here so I don't forget.

Here's the problem. If you run models inside a loop, the information about models is not properly documented as part of the output. There is a small data set on house prices that can help illustrate this problem. Here are the first five rows of the data set.

`> housing[1:5,]`

sqft age feats nec cust cor price

1 2650 13 7 1 1 0 205000

2 2600 NA 4 1 1 0 208000

3 2664 6 5 1 1 0 215000

4 2921 3 6 1 1 0 215000

5 2580 4 4 1 1 0 199900

The first three variables are the square footage, age, and the number of special features of the house. The next three variables are indicators for whether the house is in the northeast corner of the city, whether it is a custom built house, and whether it is on a corner lot. The last variable is the sales price of the house. You might be interested in what variables predict sales price. Part of the preliminary analysis would be to look at simple univariate regression before fitting a more complex model. You could do this inside a loop, but when you do, the information about the individual variables is not carried along with the output. For example, this simple loop

`for (i in 1:6) {print(coef(lm(price~housing[,i])))}`

produces the following:

` (Intercept) housing[, i] `

4781.93066 61.36668

(Intercept) housing[, i]

116847.00710 -24.75735

(Intercept) housing[, i]

66117.42 11375.94

(Intercept) housing[, i]

97282.05 13487.18

(Intercept) housing[, i]

94752.22 49925.56

(Intercept) housing[, i]

107718.947 -7687.129

The same problem occurs if you work with a function:

`univ.coef <- function(dv,iv) {coef(lm(dv~iv))}`

univ.coef(price,sqft)

which produces the following output

`(Intercept) iv `

4781.93066 61.36668

Inside a loop, you can paste the model together.

`for (i in 1:6) {`

tmp.formula <- as.formula(paste("price ~",names(housing)[i]))

print(coef(lm(tmp.formula)))

}

which produces the following output

` (Intercept) sqft`

4781.93066 61.36668

(Intercept) age

116847.00710 -24.75735

(Intercept) feats

66117.42 11375.94

(Intercept) nec

97282.05 13487.18

(Intercept) cust

94752.22 49925.56

(Intercept) cor

107718.947 -7687.129

This also works within a function, but you have to place your variable names in quotes.

`univ.coef <- function(dvname,ivname) {`

tmp.formula <- as.formula(paste(dvname,"~",ivname))

coef(lm(tmp.formula))

}

univ.coef("price","sqft")

which produces the following output

` (Intercept) sqft`

4781.93066 61.36668

There was a similar question about functions. Suppose you have a character vector that represented the name of a function. You could convert that string to the actual function with the match.fun function. For example,

`test.data <- 1:10`

flist <- c("min","mean","max")

stat <- numeric(0)

for (i in 1:length(flist)) {

fun <- match.fun(flist[i])

stat[i] <- fun(test.data)

}

stat

produces the following output

` [1] 1.0 5.5 10.0`

Another more complicated approach is

`test.data <- 1:10`

flist <- c("min","mean","max")

stat <- numeric(0)

for (i in 1:length(flist)) {

stat[i] <- eval(as.call(list(as.name(flist[i]), test.data)))

}

stat

which produces the following output

` [1] 1.0 5.5 10.0`

There's nothing wrong, though, with storing the functions themselves

`test.data <- 1:10`

flist <- c(min,mean,max)

stat <- numeric(0)

for (i in 1:length(flist)) {

stat[i] <- flist[[i]](test.data)

}

`stat`

which produces the following output

` [1] 1.0 5.5 10.0`

You have to use double brackets because functions are combined as a list, not as a vector.

You might ask yourself, why go to all this trouble. One advantage of incorporating variables names from a list into a model or converting the string name of a function into the function itself is to that you can use the same string to create dimension names in a matrix, or incorporate those strings into the title of a graph. It also allows you to dynamically change the function list within the program.