I think I asked a similar question 3 years ago to the Splus list and I think the answer was no or noone answered so noone should spend more than 5 minutes on this because it could definitely be a waste of time. My question is whether the function below can be rewritten without a for loop. apply is fine if it can be done that way but i doubt it. I call it a lot and would prefer to not loop. #----------------------------------------------------------------------- -------------------------- constructLt<-function(invector) { outvector<-invector for ( i in 2:length(invector) ) { if ( invector[i] < 1 ) { outvector[i]<-invector[i]*outvector[i-1] } } return(outvector) } #----------------------------------------------------------------------- ------------------------- -------------------------------------------------------- This is not an offer (or solicitation of an offer) to buy/sell the securities/instruments mentioned or an official confirmation. Morgan Stanley may deal as principal in or own or act as market maker for securities/instruments mentioned or may advise the issuers. This is not research and is not from MS Research but it may refer to a research analyst/research report. Unless indicated, these views are the author's and may differ from those of Morgan Stanley research or others in the Firm. We do not represent this is accurate or complete and we may not update this. Past performance is not indicative of future returns. For additional information, research reports and important disclosures, contact me or see https://secure.ms.com/servlet/cls. You should not use e-mail to request, authorize or effect the purchase or sale of any security or instrument, to send transfer instructions, or to effect any other transactions. We cannot guarantee that any such requests received via e-mail will be processed in a timely manner. This communication is solely for the addressee(s) and may contain confidential information. We do not waive confidentiality by mistransmission. Contact me if you do not wish to receive these communications. In the UK, this communication is directed in the UK to those persons who are market counterparties or intermediate customers (as defined in the UK Financial Services Authority's rules). [[alternative HTML version deleted]]
On Tue, 2006-10-24 at 14:36 -0400, Leeds, Mark (IED) wrote:> I think I asked a similar question 3 years ago to the Splus list and I > think the answer was no or noone answered so noone should spend more > than 5 minutes on this > because it could definitely be a waste of time. > > My question is whether the function below can be rewritten without a for > loop. apply is fine if it can be done that way but i doubt it. I call it > a lot and would > prefer to not loop. > > #----------------------------------------------------------------------- > -------------------------- > > constructLt<-function(invector) { > > outvector<-invector > > for ( i in 2:length(invector) ) { > if ( invector[i] < 1 ) { > outvector[i]<-invector[i]*outvector[i-1] > } > } > > return(outvector) > > }You sure can vectorize this. Try this below... I haven't tested, but it should be close to your solution. There's also a <- invector[-1] outvector <- invector wh <- which(a<1)+1 outvector[wh] <- a[wh] * invector[-length(invector)][wh-1] outvector HTH, Jerome -- Jerome Asselin, M.Sc., Agent de recherche, RHCE CHUM -- Centre de recherche 3875 rue St-Urbain, 3e etage // Montreal QC H2W 1V1 Tel.: 514-890-8000 Poste 15914; Fax: 514-412-7106
Try this (essentially the trick is to shift the invector to get the y[i-i] effect): constructLt<-function(invector, a=1) { invector[invector<a] <- c(0,invector)[invector<a] * invector[invector<a] invector }> aa <- c(1,1,0.5,2,3,0.4,4,5) > aa[1] 1.0 1.0 0.5 2.0 3.0 0.4 4.0 5.0> constructLt(aa)[1] 1.0 1.0 0.5 2.0 3.0 1.2 4.0 5.0 -Christos -----Original Message----- From: r-help-bounces at stat.math.ethz.ch [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Leeds, Mark (IED) Sent: Tuesday, October 24, 2006 2:36 PM To: R-help at stat.math.ethz.ch Subject: [R] avoiding a loop I think I asked a similar question 3 years ago to the Splus list and I think the answer was no or noone answered so noone should spend more than 5 minutes on this because it could definitely be a waste of time. My question is whether the function below can be rewritten without a for loop. apply is fine if it can be done that way but i doubt it. I call it a lot and would prefer to not loop. #----------------------------------------------------------------------- -------------------------- constructLt<-function(invector) { outvector<-invector for ( i in 2:length(invector) ) { if ( invector[i] < 1 ) { outvector[i]<-invector[i]*outvector[i-1] } } return(outvector) } #----------------------------------------------------------------------- ------------------------- -------------------------------------------------------- This is not an offer (or solicitation of an offer) to buy/sell the securities/instruments mentioned or an official confirmation. Morgan Stanley may deal as principal in or own or act as market maker for securities/instruments mentioned or may advise the issuers. This is not research and is not from MS Research but it may refer to a research analyst/research report. Unless indicated, these views are the author's and may differ from those of Morgan Stanley research or others in the Firm. We do not represent this is accurate or complete and we may not update this. Past performance is not indicative of future returns. For additional information, research reports and important disclosures, contact me or see https://secure.ms.com/servlet/cls. You should not use e-mail to request, authorize or effect the purchase or sale of any security or instrument, to send transfer instructions, or to effect any other transactions. We cannot guarantee that any such requests received via ! e-mail will be processed in a timely manner. This communication is solely for the addressee(s) and may contain confidential information. We do not waive confidentiality by mistransmission. Contact me if you do not wish to receive these communications. In the UK, this communication is directed in the UK to those persons who are market counterparties or intermediate customers (as defined in the UK Financial Services Authority's rules). [[alternative HTML version deleted]] ______________________________________________ R-help at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Mark, This is hardly a one-liner. It will only help you if you call it with large objects. If you have 0 in your data it needs even more extending. Here it is: myconstruct <- function(aa) { aa <- c(1,1,aa,1) bb <- cumprod(aa) taa <- aa<1 difftaa <- diff(taa) starts <- which(c(FALSE,difftaa==1)) ends <- which(c(FALSE,difftaa==-1)) correction <- rep(0,length(aa)) correction[starts] <- 1/bb[starts-2] correction[ends] <- -1/bb[starts-2] correction <- cumsum(correction) correction[correction==0] <- 1 correction bbcor <- bb*correction bbcor[!taa] <- aa[!taa] bbcor[c(-1,-2,-length(bbcor))] } aa <- runif(10000,min=.5,max=1.5) system.time(target <- constructLt(aa)) system.time(found <- myconstruct(aa)) identical(target,found) max(abs(target-found))> system.time(target <- constructLt(aa))[1] 0.059 0.001 0.059 0.000 0.000> system.time(found <- myconstruct(aa))[1] 0.013 0.000 0.014 0.000 0.000> identical(target,found)[1] FALSE> max(abs(target-found))[1] 4.440892e-16>Appearently the outcome is different is some low decimal, due to other calculation method. Kees On Tuesday 24 October 2006 20:36, Leeds, Mark (IED) wrote:> I think I asked a similar question 3 years ago to the Splus list and I > think the answer was no or noone answered so noone should spend more > than 5 minutes on this > because it could definitely be a waste of time. > > My question is whether the function below can be rewritten without a for > loop. apply is fine if it can be done that way but i doubt it. I call it > a lot and would > prefer to not loop. > > #----------------------------------------------------------------------- > -------------------------- > > constructLt<-function(invector) { > > outvector<-invector > > for ( i in 2:length(invector) ) { > if ( invector[i] < 1 ) { > outvector[i]<-invector[i]*outvector[i-1] > } > } > > return(outvector) > > } > > #----------------------------------------------------------------------- > ------------------------- > -------------------------------------------------------- > > This is not an offer (or solicitation of an offer) to buy/sell the > securities/instruments mentioned or an official confirmation. Morgan > Stanley may deal as principal in or own or act as market maker for > securities/instruments mentioned or may advise the issuers. This is not > research and is not from MS Research but it may refer to a research > analyst/research report. Unless indicated, these views are the author's > and may differ from those of Morgan Stanley research or others in the Firm. > We do not represent this is accurate or complete and we may not update > this. Past performance is not indicative of future returns. For > additional information, research reports and important disclosures, contact > me or see https://secure.ms.com/servlet/cls. You should not use e-mail to > request, authorize or effect the purchase or sale of any security or > instrument, to send transfer instructions, or to effect any other > transactions. We cannot guarantee that any such requests received via ! > e-mail will be processed in a timely manner. This communication is solely > for the addressee(s) and may contain confidential information. We do not > waive confidentiality by mistransmission. Contact me if you do not wish to > receive these communications. In the UK, this communication is directed in > the UK to those persons who are market counterparties or intermediate > customers (as defined in the UK Financial Services Authority's rules). > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html and provide commented, minimal, > self-contained, reproducible code.
On Wednesday 25 October 2006 07:36, Leeds, Mark (IED) wrote:> I think I asked a similar question 3 years ago to the Splus list and I > think the answer was no or noone answered so noone should spend more > than 5 minutes on this > because it could definitely be a waste of time. > > My question is whether the function below can be rewritten without a for > loop. apply is fine if it can be done that way but i doubt it. I call it > a lot and would > prefer to not loop. > > #----------------------------------------------------------------------- > -------------------------- > > constructLt<-function(invector) { > > outvector<-invector > > for ( i in 2:length(invector) ) { > if ( invector[i] < 1 ) { > outvector[i]<-invector[i]*outvector[i-1] > } > } > > return(outvector) > > } >Depending on the nature of your data, there is a faster way. It still involves looping, but not over the entire vector. Try the following: constructLt <- function(invector) { outvector <- invector cs <- cumsum(rle(invector < 1)$lengths) if (invector[1] < 1) cs <- c(1, cs) for (i in 0:(length(cs)%/%2 - 1)){ starti <- cs[2*i + 1] stopi <- cs[starti + 1] outvector[starti:stopi] <- cumprod(invector[starti:stopi]) } return(outvector) } It is in the order of 3 times as fast for random vectors of considerable length (> 1000). For random vectors of length 50 it is about the same speed as the full looping algorithm. However if the data is such that there are longer runs (than N(1, 1)), then you might expect a better speedup. HTH Ray Brownrigg