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