> On 23 Dec 2014, at 23:57 , Pooya Lalehzari <[email protected]> wrote:
> 
> Hello,
> I have a data.frame (below) containing the two fields of "Value" and "Signal" 
> and I would need to create the third field of "To_Be_Produced". The condition 
> for producing the third field is to carry the 1 in the "Signal" field down 
> until "Value" is below 40.
> Do I have to create a for-loop to do this or will I be able to do anything 
> else more efficient?
> 
> 
> df <- data.frame( Value=c(0,0,100,85,39,1,30,40,20,20,0,0),
>                  Signal=c(0,1,0,0,0,0,0,0,0,1,0,0),
>                  To_Be_Produced= c(0,1,1,1,0,0,0,0,0,1,0,0)
>                )

I'd go with the for loop, unless you _really_ need the efficiency. And if you 
do need efficiency that badly, it is probably better to code up the for loop in 
C/C++. (An Rcpp evangelist is likely to chime in any moment now.)

If you want a vectorized solution just for the academic exercise, I think you 
can do something with ave(), grouping by cumsum(Signal) and within groups doing 
cumprod(Value >= 40), except that you need to skip the first element of each 
group. And be careful that the first group is different.

This seems to do it:

> with(df, ave(Value, cumsum(Signal), FUN=function(x) c(0,cumprod(x[-1]>=40))
              ) + Signal)
 [1] 0 1 1 1 0 0 0 0 0 1 0 0


-- 
Peter Dalgaard, Professor,
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Email: [email protected]  Priv: [email protected]

______________________________________________
[email protected] mailing list -- To UNSUBSCRIBE and more, see
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.

Reply via email to