0

I need help pasting a data frame column as a formula in R using the $ sign.

df1 <- data.frame(id1 = c(1, 2, 3, 4, 5),
              id2 = c(1, 2, 3, 4, 5),
              var1 = c(3,6,6,9,5),
              var2 = c(1, 1, 0, 0, 1))
rownames(df1)<-c("first","second","third","fourth","fifth")

trait=c("id1","id2")
list=as.character("var1","var2")

for(i in trait){
  fit <- lm(df1[,i]~df1$list[2])
}

I want to paste the second part of the lm (df1$list[2]). After the $, I want that it pastes the corresponding element of the character vector list.

Olympia
  • 457
  • 8
  • 19
  • You [can't use $ with variables](https://stackoverflow.com/questions/18222286/dynamically-select-data-frame-columns-using-and-a-vector-of-column-names). Use the more general `[` indexing operator. – MrFlick Oct 09 '19 at 15:26
  • allright, I looked that up and replaced t like that: fit <- lm(df1[,i]~df1[,list[2]]) .But this solution doesn't work when it's not coming from the same dataframe: I have here df1 and list, and list comes in my real dataframe from a loop output- So how can I fit the model if the variable after the $ sign is not the same as df1? – Olympia Oct 10 '19 at 07:47
  • Why doesn’t it work it they are not from the same data frame? What error do you get? I assume both data frames have the same number of rows otherwise the regression wouldn’t make any sense. – MrFlick Oct 10 '19 at 13:03
  • I get the following error when I replace the line I mentioned in the comment above: Error in `[.data.frame`(df1, , list[2]) : undefined columns selected – Olympia Oct 11 '19 at 09:40
  • Not sure why you have `as.character` for your `list` variable. Also you want to iterate two lists at the same time so better to iterate over the index. Something like this should work `trait=c("id1","id2"); list=c("var1","var2"); for(i in seq_along(trait)) {fit <- lm(df1[,trait[i]]~df1[,list[i]])}` – MrFlick Oct 11 '19 at 15:34
  • 1
    Another good option would be `for(i in seq_along(trait)) {fit <- lm(reformulate(list[i], trait[i]), df1); print(fit)}` – MrFlick Oct 11 '19 at 15:35
  • thank you very much, that worked! If you post it as an answer, I will accept and upvote it! – Olympia Oct 13 '19 at 12:33

2 Answers2

1

lm can run multiple left hand sides at once:

lm(cbind(id1, id2) ~ var1 + var2, f1)

giving:

Call:
lm(formula = cbind(id1, id2) ~ var1 + var2, data = f1)

Coefficients:
             id1      id2    
(Intercept)  0.09091  0.09091
var1         0.45455  0.45455
var2         0.45455  0.45455
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • thank you, but my problem is that the list elements are essential. I tried this but it does not work: list=as.character("var1","var2") lm(as.formula(paste(id1 ~ list[2])), data = df1) – Olympia Oct 10 '19 at 07:53
0

The answer that worked best for me was that of MrFlick above:

for(i in seq_along(trait)) {
fit <- lm(reformulate(list[i], trait[i]), df1); print(fit)}
Olympia
  • 457
  • 8
  • 19