12-03-2015 01:06 PM
Hi I am tring to keep all even records for a data and using the where mod(_n_,2) = 0, but it does not work. However if works.
Does that mean _n_ is actaully for the data statment instead of set statment?
12-03-2015 01:14 PM
WHERE operates differently than IF. WHERE examines the observation before reading it in ... so any fields that you refer to must be part of the incoming data set when using a WHERE statement. That would exclude _n_ which is not part of the data set but is only created when the DATA step executes.
12-03-2015 01:31 PM
Under conditions such as automatic variable, new variable created within data step, first. by, last. by, if must be used, _n_ is automatic variable produced in data step, so you must use if.
12-03-2015 02:26 PM - edited 12-03-2015 02:31 PM
You can do it in a where statement (or where option) if you use the monotonic() function. The function behaves in a roughly comparable manner to that of _n_. It even works in PROC SQL, which disallows the variable _n_!
DATA have; LENGTH name $10; name='Jack'; id=555; output; name='Jill'; id=333; output; name='Bonnie'; id=777; output; name='Clyde'; id=123; output; RUN; /* version 1: PROC SQL */ PROC SQL; CREATE TABLE want1 AS SELECT * FROM have WHERE MOD(MONOTONIC(), 2) = 0;
/* beware: avoid including an ORDER BY statement here */
/* because the results will be misleading */ QUIT; /* version 2: data step WHERE */ DATA want2; SET have; WHERE MOD(MONOTONIC(), 2) = 0; RUN; /* version 3: data step WHERE option */ DATA want3; SET have(WHERE=(MOD(MONOTONIC(), 2) = 0)); RUN;
12-06-2015 12:00 AM - edited 12-06-2015 12:02 AM
Seems like the undocumented monotonic() function simply counts the number of times it is called, which can give it a value other than _n_
data _null_; set sashelp.class(obs=3); /* Many calls on each data step iteration */ do i = 1 to 2; n = monotonic(); m = _n_; end; /* Skipped calls on some data step iterations */ if mod(_n_,2)=1 then do; r = monotonic(); s = _n_; end; put (n m r s) (=); run;