An error while looping a linear regression

80 views Asked by At

I would like to run a loop that will run per each category of one of the variables and produce a prediction per each regression so that the sum of the prediction variable will be deduced from the target variable .Here Is my toy data and code:

df <- read.table(text = "target birds    wolfs     snakes
                     3        9         7 a
                     3        8         4 b
                     1        2         8 c
                     1        2         3 a
                     1        8         3 a
                     6        1         2 a
                     6        7         1 b
                     6        1         5 c
                     5        9         7 c
                     3        8         7 c
                     4        2         7 b
                     1        2         3 b
                     7        6         3 c
                     6        1         1 a
                     6        3         9 a
                     6        1         1 b ",header = TRUE)

I wrote this code(below) that it's aim was to get the results of the calculation written above but I got an error while :

Here is the code:

b <- list()
   for(i in c("a","b",'c')){
     lmModel <- lm(target ~ birds+wolfs, data = subset(df, snakes == i) )
     b[i] <- sum(predict(lmModel,newdata=subset(df, snakes == i)))  - sum(df$target[which(df$snakes=='a'),])

}
 b <- as.numeric(b)
 b

I got this error:

  Error in df$target[which(df$snakes == "a"), ] : 
  incorrect number of dimensions

How can I solve this issue?

1

There are 1 answers

0
James On BEST ANSWER

The problem arises from you mixture of subsetting types here: df$target[which(df$snakes=='a'),]

Once you use $ the output is no longer a data.frame, and the two parameter [ subsetting is no longer valid. You are better off compacting it to:

sum(df[df$snakes=="a","target"])
[1] 23

As for your model, you can just create one with snakes as a covariate, and use the predictions from that to sum in the snakes groups:

lm(target~birds+wolfs+snakes+0,df)

Call:
lm(formula = target ~ birds + wolfs + snakes + 0, data = df)

Coefficients:
   birds     wolfs   snakesa   snakesb   snakesc  
-0.08593  -0.23461   5.15458   5.09446   6.25448

tapply(predict(lm(target~birds+wolfs+snakes+0,df)),df$snakes,sum)
 a  b  c 
23 20 22 

And to get the final output of your b variable,

tapply(predict(lm(target~birds+wolfs+snakes+0,df)),df$snakes,sum) - sum(df[df$snakes=="a","target"])
            a             b             c 
 1.776357e-14 -3.000000e+00 -1.000000e+00 

but note that there is a small numerical discrepancy for the a value.

Alternatively, and to check, you can specify subsets of data via an argument to lm:

sum(predict(lm(target~birds+wolfs,data=df,subset=snakes=="a")))
[1] 23
sum(predict(lm(target~birds+wolfs,data=df,subset=snakes=="b")))
[1] 20
sum(predict(lm(target~birds+wolfs,data=df,subset=snakes=="c")))
[1] 22