0

I'm under the pump by coworkers to stop using for loops so much, but I'm not great with apply functions either.

What I need to do is to regress multiple companies against a fixed reference value, which I can achieve easily with a for loop, but not so much using the apply family.

My data and for loop look like:

      Date    AANRI    AGLRI  APARI   ASTRI  ASXRI  DUERI   ENVRI   GASRI HDFRI  SKIRI
1: 2006-01-06 504.86 26443.30 255.75 101.15 28050.84 108.77 247.71 169.61 99.03 100.00
2: 2006-01-13 498.86 26618.78 252.21 100.00 28324.59 110.70 251.43 171.67 99.18 103.36
3: 2006-01-20 492.41 27734.33 255.67 100.38 28436.87 110.41 247.41 169.61 98.92 101.68
4: 2006-01-27 498.86 28850.82 264.88  99.23 28815.26 111.90 246.70 173.74 98.26  99.16
5: 2006-02-03 497.48 28164.16 265.79 100.38 28614.28 111.16 244.88 170.98 99.64  97.48
6: 2006-02-10 500.71 28104.86 262.23 101.54 28567.93 112.21 248.63 173.05 99.38  98.32

And my for loop:

reg1_store <- list()
for(i in names(RI_c)[!grepl("ASX|Date", names(RI_c))]){
  reg1_store[[i]] <- lm(get(i) ~ ASXRI, data = RI_c)
}

This works fine, I am able to regress the separate companies on the ASX and store them accordingly.

I am wondering how I can replicate this with an apply function?

Gin_Salmon
  • 837
  • 1
  • 7
  • 19
  • Hi @ZheyuanLi, your suggested link is indeed helpful and I think it would potentially be of help later. However, my main reason for raising this question was purely to see if it were possible to substitute the for loop for an apply function. – Gin_Salmon Sep 28 '16 at 04:51

1 Answers1

0

@zhequan-li offers a very efficient solution. If efficiency is not a consideration and you want the results in a list, you should use lapply. The main idea is to give lapply a vector of tickers (companies for the left-hand-side), paste each ticker into a character string of the form "X ~ ASXRI", then call lm on that formula.

tickers <- names(RI_c)[!grepl("ASX|Date", names(RI_c))]
reg1_store <- lapply(tickers, function(x) {
  lm(paste(x, "~ ASXRI"), RI_c)
})

# To name the elements of your list
names(reg1_store) <- tickers
Weihuang Wong
  • 12,868
  • 2
  • 27
  • 48
  • @Weihuang Wong, thanks! Just what I was after. I have a couple of questions though! I'm very familiar with function notation in general, but in this case, when you write `function(x) {lm(paste(x, "~ ASXRI"), RI_c)`, is `RI_c` being parsed to the function, i am confused as to how i determine what takes the value of x in the function. Secondly, does lapply know that I want to loop through each individual column? – Gin_Salmon Sep 28 '16 at 04:57
  • `lapply` iterates over the value of the first (more precisely the `X`) argument. In this case it is the vector of tickers; in each iteration, `lapply` passes one element of that vector (one ticker) into `function(x)`. Perhaps it may be useful to work through the examples in `?lapply`. – Weihuang Wong Sep 28 '16 at 05:11
  • @ZheyuanLi: I did think about whether to answer. I concluded that the question was less about `lm` than how to convert a for-loop into `lapply` (and as such, it *is* probably a dupe of many questions on SO), and I thought it would be helpful to OP to just provide a straightforward answer to the question. I hear you, though. While I have you, thanks for that linked answer. I did not know about `mlm` until today. – Weihuang Wong Sep 28 '16 at 05:21