Date: Wed, 21 Apr 1999 22:24:09 +0100
Reply-To: R P Bullock <{$news$}@rerun.demon.co.uk>
Sender: "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From: R P Bullock <{$news$}@NOSPAM.DEMON.CO.UK>
Subject: Re: How to dedect frequent sign changes
In article <7fknbs$3l4$1@nnrp1.dejanews.com>, wenyu1030@my-dejanews.com
writes
>Hi,
>
>I am trying to write an efficient SAS code to handle the following question.
>
>Suppose I have a SAS dataset created with ID number and a variable x.
>Observations of x consist of consecutive positive numbers followed by
>consecutive negative numbers, and then maybe consecutive positive numbers
>again. in fact, this is a large data set so such sign changes may occur more
>than a number of times. The dataset may look something like this:
>
>
>1 2
>2 3
>3 -1
>4 -2
>5 7
>6 8
>7 -9
>8 -9
>
>What I want to do is to output the observation whenever its sign changes,
>i.e., its sign is different from its previous one----such as observation 3, 5,
>and 7 in the above dataset.
>
>Can somebody suggest an efficient code for solving this problem?
>
>Thanks.
>
>wenyu
>
>-----------== Posted via Deja News, The Discussion Network ==----------
>http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
To add to the suggestions already made:
data test;
input id x;
cards;
1 2
2 3
3 -1
4 -2
5 7
6 8
7 -9
8 -9
;
data changes(drop=sign);
set test;
sign=sign(x);
if sign^=lag(sign);
if _n_^=1;
run;
Notes:
The sign function will return +1, 0 or -1 depending on whether the
argument is +ve, zero or -ve.
The 'lag' function returns the value of the variable from the previous
observation and is initially set to missing. It maintains a stack of
previous variable values (in this example there is only one on the
stack), but only adds to the stack when it is executed. If the 'lag'
statement is wrapped within a conditional clause, it may not return the
value you expect. Here it is executed for every observation.
'if _n_^=1;' drops the first observation - omit if you want it output.
This statement is placed after the first subsetting 'if' to minimise the
number of times it is executed.
An observation will be output if x has a value of zero or is missing.
If this is a problem then further coding will be necessary. If x is
missing, 'sign(x)' will yield a note on the log concerning missing
values. I prefer to code around such an event to ensure that this
message indicates that something unexpected has happened.
As 'lag(x)' is initially set to missing, if the variable x in the first
observation is missing, it would not be output anyway. If the second,
third, etc. observations are also missing, nothing will be output until
a non-missing value is encountered.
Bob
--
R P Bullock