-1

I have this example data

    library(quantmod)
    getSymbols("NOK",from="2013-01-01",to="2014-05-01",src="yahoo","getSymbols.warning4.0"=FALSE)
    data<-NOK
    w1<-1
    L_dO<-data[,1]
      L_dC<-data[,4]
      L_Profit_L_1<-((lag(L_dC,-1)-lag(L_dO,-1))/(lag(L_dO,-1)))*100
      L_Profit_L_2<-((lag(L_dC,-2)-lag(L_dO,-1))/(lag(L_dO,-1)))*100
      L_Profit_L_3<-((lag(L_dC,-3)-lag(L_dO,-1))/(lag(L_dO,-1)))*100
      L_Profit_L_4<-((lag(L_dC,-4)-lag(L_dO,-1))/(lag(L_dO,-1)))*100
      L_Profit_L_5<-((lag(L_dC,-5)-lag(L_dO,-1))/(lag(L_dO,-1)))*100
      L_Profit_L_all<-ifelse(L_Profit_L_1>w1,L_Profit_L_1,
                             ifelse(L_Profit_L_2>w1,L_Profit_L_2,
                                    ifelse(L_Profit_L_3>w1,L_Profit_L_3,
                                           ifelse(L_Profit_L_4>w1,L_Profit_L_4,
                                           ifelse(L_Profit_L_5>w1,L_Profit_L_5,L_Profit_L_5)))))

What am I interested in is L_Profit_L_all, but I see this is a bit strange and slow way to write it. I have tried to vectorize it like

L_Profit_L_all<-ifelse(c(L_Profit_L_1>w1,L_Profit_L_2>w1,L_Profit_L_3>w1,L_Profit_L_4>w1,L_Profit_L_5>w1),c(L_Profit_L_1,L_Profit_L_2,L_Profit_L_3,L_Profit_L_4,L_Profit_L_5),L_Profit_L_5)

But th result is not the same. I want it to work in right order, i.e. if the first if condition is TRUE, then return first else condition (and don't care about if another condition is TRUE which is able to do the first code) Any straightforward how to achieve it? I have a huge dataset so every ms is good to save. Thanks

nicola
  • 24,005
  • 3
  • 35
  • 56
Bury
  • 527
  • 2
  • 5
  • 15
  • 1
    see the answers here http://stackoverflow.com/questions/27902821/create-column-with-grouped-values-based-on-another-column-in-dplyr/27902924#27902924 – Khashaa Jan 13 '15 at 07:15

1 Answers1

1

Here's an example how you might approach the problem without any ifelses. Assume you cbind all your L_Profit_L_X vectors together to get something similar to m in my example.

set.seed(1)
m <- matrix(sample(-5:5, 50, T), ncol = 5)
indx <- max.col(m > 1, ties.method = "first")
sapply(seq_along(indx), function(i) m[i, indx[i]])
#[1] 5 2 2 4 3 4 5 2 4 3

This is not fully vectorized since we're using sapply but I'm sure it will be a lot faster than the initial approach with 5 nested ifelses.

Update

You can vectorize the code by replacing the sapply part above with:

m[cbind(seq_len(nrow(m)), indx)]
# [1] 5 2 2 4 3 4 5 2 4 3
talat
  • 68,970
  • 21
  • 126
  • 157