[Thread Prev][Thread Next][Index]
Re: [ferret_users] count consecutive events
Hi Patrick,
I had a similar problem some years ago - counting runs in sequences
of 0's and 1's -- but just thought of a better way to do it, using the
@cia transformation. One identifies "start" and "end" points in the
sequence then, whereever a "start" is found, looking for where the "next
end above" is located.
The method results in short, independent definitions for each run
length, and lends itself to use in a repeat loop. A demo script (when
the sequence is along the x-axis) is attached but the key points are:
! define start points (a 1 preceded by a 0) for the runs in the sequence "v"
let/title="Run Starts" start=if(v eq 1 and v[i=@shf:-1] eq 0)then 1
! ... and end points (a 1 followed by a 0)
let/title="Run Ends" end=if(v eq 1 and v[i=@shf:1] eq 0)then 1
! then the start points of runs of length "n" are given by the mask "run"
let run=IF(START EQ 1 AND END[I=@CIA] EQ `n-1`)then 1
! and to count them
list run[i=@ngd]
Hope it helps,
Mick
---------
Brockmann Patrick wrote:
Hi all,
Is there a way to count consecutive events ?
From climate indice variables, I would like to have the number
of continuous events, for 1, 2, 3, 4, ..., n events.
B C1EVN C2EVN C3EVN C4EVN
1 / 1: 0.000 .... .... .... ....
2 / 2: 1.000 1.000 .... .... ....
3 / 3: 0.000 .... .... .... ....
4 / 4: 1.000 1.000 .... .... ....
5 / 5: 0.000 .... .... .... ....
6 / 6: 1.000 1.000 .... .... ....
7 / 7: 0.000 .... .... .... ....
8 / 8: 1.000 1.000 .... .... ....
9 / 9: 0.000 .... .... .... ....
10 / 10: 0.000 .... .... .... ....
11 / 11: 0.000 .... .... .... ....
12 / 12: 1.000 .... 1.000 .... ....
13 / 13: 1.000 .... .... .... ....
14 / 14: 0.000 .... .... .... ....
15 / 15: 1.000 .... 1.000 .... ....
16 / 16: 1.000 .... .... .... ....
17 / 17: 0.000 .... .... .... ....
18 / 18: 0.000 .... .... .... ....
19 / 19: 1.000 .... 1.000 .... ....
20 / 20: 1.000 .... .... .... ....
21 / 21: 0.000 .... .... .... ....
22 / 22: 0.000 .... .... .... ....
23 / 23: 1.000 1.000 .... .... ....
24 / 24: 0.000 .... .... .... ....
25 / 25: 0.000 .... .... .... ....
26 / 26: 1.000 .... .... .... 1.000
27 / 27: 1.000 .... .... .... ....
28 / 28: 1.000 .... .... .... ....
29 / 29: 1.000 .... .... .... ....
30 / 30: 0.000 .... .... .... ....
...
C1EVN represents events for 1 period at 1
C2EVN represents events for 2 consecutive periods at 1
C3EVN represents events for 3 consecutive periods at 1
C4EVN represents events for 4 consecutive periods at 1
...
Attached is a exemple I have scripted. It works well for a 52 points
variable
when I look for for 1 to 4 consecutive events.
As the real case is to compute this over a year of 360 days looking for
consecutive events of 30 days, I need to define variables from very
long expressions.
and in this case I get the message :
**ERROR: expression too complex
Let me know if there a solution to this.
Patrick
åå
! Counting runs of 1's in a sequence of 0's and 1's
! generate a series of 0's and 1's and list to a file ...
let rv=if(randu(i) ge 0.45)then 1 else 0
list/nohead/i=1:360/file=runtest.d/form=(f3.0) rv
! ... then read them back
def axis/x=1:360:1 xax ; def grid/x=xax grd
file/form=free/var=v/g=grd runtest.d
! define start points for the runs (a 1 preceded by a 0)
let/title="Run Starts" start=if(v eq 1 and v[i=@shf:-1] eq 0)then 1
! ... and end points (a 1 followed by a 0)
let/title="Run Ends" end=if(v eq 1 and v[i=@shf:1] eq 0)then 1
! define some simple runs (of 1, 2, 3, or 4 ones in a row)
! a run of length 1 starts and ends at the same point
! let run1=if(start*end eq 1)then 1
! ... or equivalently
let run1=if(start eq 1 and end[i=@cia] eq 0)then 1
! a run of length 2 has its end "one point ahead" ...
let run2=if(start eq 1 and end[i=@cia] eq 1)then 1
! a run of length 3 has its end "two points ahead" ...
let run3=if(start eq 1 and end[i=@cia] eq 2)then 1
! and so on
let run4=if(start eq 1 and end[i=@cia] eq 3)then 1
! since these expressions are short and independent you can
! define as many as you like ...
! ... and verify that you match the results from a test listing
list/nohead/i=1:52/form=(f2.0) v
list/nohead/i=1:52 run1[i=@ngd],run2[i=@ngd],run3[i=@ngd],run4[i=@ngd]
message
! to look at multiple run lengths you could employ a repeat loop
! --- lets increase the probability of "ones" to get some longer runs
let rv=if(randu(i) ge 0.1)then 1 else 0
list/nohead/i=1:10000/file=runtest.d/form=(f3.0)/clob rv
can data 1 ; def axis/x=1:10000:1 xax ; def grid/x=xax grd
file/form=free/var=v/g=grd runtest.d
message
! lets list the number of runs of lengths 1-30 in this 10000 point sequence
sp touch run.results
repeat/range=1:30/name=n (let run=IF(START EQ 1 AND END[I=@CIA] EQ `n-1`)then 1 ;\
list/nohead/app/form=(2f6.0)/file=run.results n,run[i=@ngd] )
! and make a bar chart of the results
let bx=ysequence({-0.5,0.5,0.5,-0.5}) ; let by=ysequence({0,0,1,1})
file/form=free/var=length,hits run.results
poly/nolab/pal=black/coord=y/set bx+length,by*hits
ppl yfor,(i3) ; ppl xfor,(i2) ; ppl xaxis,0.5,30.5,1 ; ppl axlint,1 ; ppl fillpoly
q
[Thread Prev][Thread Next][Index]
Contact Us
Dept of Commerce /
NOAA /
OAR /
PMEL /
TMAP
Privacy Policy | Disclaimer | Accessibility Statement