*****************************************************************************;
**                                                                         **;
**  This is the section for introducing the Datasets                       **;
**                                                                         **;
*****************************************************************************;
OPTIONS NOCENTER;
proc format;
value born_in 1="NE"
              2="SE"
              3="NW"
              4="SW"
              5="Intnl";
run;


data humans (sortedby=name);;
infile datalines missover firstobs=2;
input @1 name $char8. @10 time_W_co @15 sex $char1. @18 job $char4.  @25 line_no;
datalines;
123456789012345678901234567890
Art      1    M  Stat   1
Brent    6    M  Stat   2
Cathy    6    F  Stat   3
Debbie   5    F  Stat   4
Jen      13   F  Stat   5
Russ     2    M  Prog   6
Saad     3    M  Prog   7
Tom      6    M  Stat   8
Zim      6    M  Stat   9
;
run;


data pets (sortedby=name);
infile datalines missover firstobs=2;
input @1 name $char8. @9 repeat  @15 type $char3.  @20 Pet_nm  $char8.  ;
datalines;
123456789012345678901234567890
Art     1     Dog  Catcher
Brent   1     N
Cathy   1     Dog  R.A.
Debbie  1     Dog  Dusty
Jen     1     Cat  Princess
Jen     2     Cat  Gabbie
Jen     3     Cat  India
Mary    1     Dog  Rao
Saad    1     N
;
run;




















*****************************************************************************;
*0    Step return jump go quit                                             ;
*****************************************************************************;

*Snippet 0A  Step return jump go quit    ;
*****************************************************************************;
**                                                                         **;
**  Example of a how knowledge of the PDV is essential                     **;
**  There are no error messages, just a list of values that you must       **;
** interpret according to your expectations                                **;
** use the f4 key and binding to keys                                      **;
** look at when num-h is created- before the set statement                 **;
**                                                                         **;
*****************************************************************************;
* use this code for issuing step <RET> jump go and quit;
* This is going to take a 1 out of 2 sample from work.humans ;
data sample/debug; /*focus on _N_, values in the PDV and num_h*/
   do obsnum=1 to num_h by 2;
      set humans point=obsnum nobs=num_h;

      if _error_ then abort;
      output;
   end;
   stop;
run;






*****************************************************************************;
*1    Examine, list and describe                                             ;
*****************************************************************************;

*Snippet 1A Examine, list and describe;
*****************************************************************************;
**                                                                         **;
**  Example of a how knowledge of the PDV is essential                     **;
**  There are no error messages, just a list of values that you must       **;
** interpret according to your expectations                                **;
** use the f4 key and binding to keys                                      **;
** look at when num-h is created- before the set statement                 **;
**                                                                         **;
*****************************************************************************;
*one way to select a subset of the data - use pointer control and a do ;
*use this to practice examine list and describe commands;
data sample/debug; /*focus on _N_, values in the PDV and num_h*/
*just a non-executable comment;
   do obsnum=1 to num_h by 2;
      *another non-executable comment;
      set humans point=obsnum nobs=num_h;
      if _error_ then abort;
      output;
   end;
   stop;
run;

*Snippet 1B Examine, list and describe;
*****************************************************************************;
**                                                                         **;
**  Danger of recoding in a one to many merge                              **;

**  see the firs. and last. variables in a t of values that you must       **;
** interpret according to your expectations                                **;
** use the f4 key and binding to keys                                      **;
** look at when num-h is created- before the set statement                 **;
**                                                                         **;
*****************************************************************************;
*the danger of recoding in a one to many merge - first. and last. variables;
*use jump to skip the calculation of time _w_co;
* there is a danger, in one to many merges, in modifying variables on the one;
data matching/debug;
 merge humans(in=h) pets(in=p);
   *stop_pt=1;
   by name;
   time_W_co=time_W_co*12;
   stop_pt=1;
run;


proc print;
run;





 *Snippet 1C Examine, list and describe;
****************************************************************************
*;

**                                                                         **;
**  Look at the input buffer - not just the PDV                            **;
**  list I, b W _all_                                                      **;
**  notice that the input buffer contains Brent                            **;
**         but the variable name only contains rent                        **;
** also see the list command as a tool for managing break and watch points **;
** ISSUE THE DESCRIBE _ALL_ COMMAND  -Does show formats - see someday      **;

*****************************************************************************;
** you can compare the PDV and the input bufffer to see what is wrong with art;
data pets2 (sortedby=name)/debug;
infile datalines missover firstobs=2;
input @2 name $char8. @9 repeat 4.2 @15 type $char3.  @20 Pet_nm  $char8.
                      @9 someday ;
format someday date9.;
datalines;
123456789012345678901234567890
 Art    1     Dog  Catcher
Brent   1     N
Cathy   1     Dog  R.A.
Debbie  1     Dog  Dusty
Jen     1     Cat  Princess
Jen     2     Cat  Gabbie
Jen     3     Cat  India
Mary    1     Dog  Rao
Saad    1     N
;
run;


 *Snippet 1D Examine, list and describe;
*****************************************************************************;
**                                                                         **;
** USE THIS TO SHOW EXAMINE, SHOWING DATES WITH FORMATS, FORMATS FOR NUMBER**;
** use the f4 key and binding to keys                                      **;
** USE EXAMINE ON THIS_                                                    **;
**                                                                         **;
*****************************************************************************;
**use this code to show effect of keep on data step statement vs set statement;
**This effect show up on the mergeing of left and right on line 233;
data left;
infIle datalines missover firstobs=3;
input @1 name $char4. @8 gender 1.  @10 enroll DATE9.;
THIS_DATE=TODAY();
ENROLLED=THIS_DATE-ENROLL;
datalines;

         1         2         3         4         5
12345678901234567890123456789012345678901234567890
Sai    1 01JAN2003
Yung   1 05FEB2002
Yong   1 12MAR2002
ODD    3 22MAR2004
Sue    2 22SEP2001
Bob    1 18AUG1998
RUSS   1 19JUN1997
LIJI   1 30SEP1995
MUSA   1 20JUL2001
DEB    2 11MAR2002
;
RUN;


data RIGHT;
infIle datalines missover firstobs=3;
input @1 name $char4. @8 CHILDREN 1.  @10 SCHOOL $CHAR1. @15 HAS_BOY $CHAR1. @20 HAS_grl $CHAR1.;
THIS_DATE=TODAY();
datalines;
         1         2         3         4         5
12345678901234567890123456789012345678901234567890
Sai    1 NO   Y    N
Yung   2 YES  Y    Y
Yong   1 NO   Y    N
ODD    3 YES  Y    Y
RUSS   0      N    N
Sue    2 YES  N    Y
Bob    2 NO   Y    N
LIJI   2 NO   Y    Y
DEB    3 YES  Y    Y
;
RUN;

*SNIPPET  1D_A
**SHOW A KEEP ON THE INPUT VS A KEEP ON THE OUTPUT DATA SET;
data show_keep1(keep=F_NAME wks_enr) /debug;
set left (RENAME =(NAME=F_NAME));
wks_enr=enrolled/7;
run;

PROC PRINT;

TITLE "WE HAD MANY VARIABOLES ON THE pdv , BUT FEW IN OUTPUT DATASET";
RUN;

**A SNIPPET FOR INDEPENDENT EXPLORATION;
*CODE BELOW WILL CAUSE AN ERROR -  RENAMED VARIBLE IS ON THE pdv AND CAN NOT BE KEPT ON OUTPUT;
data show_keep2(keep=name wks_enr) /debug;

set left(keep=name wks_enr RENAME =(NAME=F_NAME));
wks_enr=enrolled/7;
run;


**ANOTHER SNIPPET FOR INDEPENDENT EXPLORATION;
** the PDV is created before the data is read, so the first definition of has_a_boy sets legngth;

** the order of Y and N, in the data does not matter;
Data Problem/DEBUG;
set right;
 if has_boy="N" then has_a_boy="NO";*use describe to see has_a_boy will be length 2;
    else has_a_boy="YES";

run;

Data OK_length/DEBUG;
set right;
 if has_boy="Y" then has_a_boy="YES";*use describe to see has_a_boy will be length 3;
    else has_a_boy="NO";
run;




*****************************************************************************;
*    BREAK, Delete Watch Trace                                               ;
*****************************************************************************;

*Snippet 2A   BREAK, Delete Watch Trace ;
**This is a GOOD TRICK. Variables from input are not retained - watch will have problems;
** variables from a set statement are retained - so less useful for vars from data set;
** run PBLM_Pets and set a watch for repeat;
**then uncomment the retain on line 290 and run again;
data Prblm_pets (sortedby=name)/debug;
infile datalines missover firstobs=2;
*retain repeat;
input @2 name $char5. @9 repeat 4.2 @15 type $char3.  @20 Pet_nm  $char8.
                      @9 someday ;
format someday date9.;
datalines;
123456789012345678901234567890
 Art    1     Dog  Catcher
 Brent  1     N
Cathy   1     Dog  R.A.
Debb    1     Dog  Dusty
Jen     1     Cat  Princess
Jen     2     Cat  Gabbie
Jen     3     Cat  India
Mary    1     Dog  Rao
Saad    1     N
;
run;


*Snippet 2B   BREAK, Delete Watch Trace ;
*****************************************************************************;
** Set break point                                                         **;
**  Look at the input buffer - not just the PDV                            **;
**  list I, b W _all_                                                      **;
**  notice that the input buffer contains Brent                            **;
**         but the variable name only contains rent                        **;
** also see the list command as a tool for managing break and watch points **;
** ISSUE THE DESCRIBE _ALL_ COMMAND  -Does show formats - see someday      **;
*****************************************************************************;
*Snippet 2A   BREAK, Delete Watch Trace ;
*use for debugger for a do loop;
*break when I = 1 and  when I = exit condition to check start and end of looping;
*you can divide the max by an integer and use in the break;
*put in a non-ececutable line;
*break with an in to break just before / after the cutpoints;
options nocenter;
data non_profit /debug;
infile datalines missover firstobs=3;
length age_grp $ 5;
input @1 name          $char8.
            @11 gender $char1.
            @13 age1 2.0
            @13 age2 2.0
            @17 From   $char8.
            @25 Q1_hrs 3.
            @30 Q2_hrs 3.
            @35 region 1.;
total= Q1_hrs + Q2_hrs;
do i=1 to age1;
  stopper="here";
  *YOU CAN ALSO DIVIDE THE MAX BY AN INTEGER AND USE IN THE BREAK;
  if i LE 12
         then age_grp ="Child";
  else if i GT 12 and i LT 20
         then age_grp ="Teen";
  else if i GE 21
         then age_grp ="Adult";
end;
pct_1= Q1_hrs  /total;
pct_2= Q1_hrs  /total;
datalines;
         1         2         3         4
1234567890123456789012345678901234567890
Sue      F  10  Florida 017  022  2
Mike     M  12  Conn    027  042  1
Erin     F  13 Ireland  021  012  5
Ya-Ching F  20  China   017  024  5
Ann      F  21  Mass    022  014  1
Jeff     M  45 Calif    078  099  4
Yuan     F  27  Nevada  026  046  4
Suna     F  31  India   017  011  5
Eric     M  45  Oregon  041  023  3
;
run;


proc print data=non_profit;
run;






*****************************************************************************;
**                                                                         **;
**  PRACTICE ON THESE EXAMPLES                                             **;
**                                                                         **;
*****************************************************************************;





*****************************************************************************;
**                                                                         **;
**  Example of if _N_=1 then set statement                                 **;
**                                                                         **;
** do this in steps, first look at data no_read                            **;
**     use the f4 key and binding of commands to keys                      **;
** USE THIS, W/ break at LOOK, TO SHOW THAT SET LAST IS VALUED BEFORE THE SET    **;
**     SHOW THAT LAST IS NOT OUTPUT TO THE DATA SET & THEN APPLY THE KEEP  **;
**     SOW AUTOMATIC RETAIN FOR VARIABLES FROM A SET STATEMENT             **;
*****************************************************************************;

data no_read/debug;
*data no_read(keep=obs_perm) /debug;
*look="look"; *coomment and uncomment this liine - examine _all_ here;
if _N_ = 0 then set left nobs=last;
obs_perm=last;
run;

proc print;
run;

data show_N_(keep=name wks_enr) /debug;
if _n_=1 then set no_read;
set left;
wks_enr=enrolled/7;
run;


*****************************************************************************;
**    NO RETAIN IF YOU USE AN INPUT STATEMENT                              **;
**  This is from the SAS help file                                         **;
**  This illustrates how there is NO retain for a input statement          **;
**  the problem show up when _n_=2                                         **;
**                                                                         **;
** USE THIS TO SHOW:                                                       **;
**   BREAKS & DELETE BREAKS, EXAMINE ALL                                   **;
**   SET A BREAK WHEN TOUR CHANGES AS AN ILLUSTRATION                      **;
**   us the f4 keys and binding to keys                                    **;
*****************************************************************************;
/* first execution */
data tours (drop=type);
*RETAIN TOUR;
infile datalines missover firstobs=3;
   input @1 type $ @;
   if type='H' then do;
      input @3 Tour $20.;
      return;
      end;
   else if type='P' then do;
      input @3 Name $10. Age 2. +1 Sex $1.;
      output;
      end;
   datalines;
         1         2         3         4         5
12345678901234567890123456789012345678901234567890
H Tour 101
P Mary E    21 F
P George S  45 M
P Susan K    3 F
H Tour 102
P Adelle S  79 M
P Walter P  55 M
P Fran I    63 F
;

proc print data=tours;
   title 'Tour List';
run;



*****************************************************************************;
**                   MERGE EXAMPLE                                         **;
** one to one, two to 1, one to two, three to two and two to three merge   **;
**                                                                         **;
** This is mostly a view of the SAS merge,and to see in=variables          **;
** use breaks examine                                                      **;
** break where r=0                                                         **;
**   use f4 and keys                                                       **;
*****************************************************************************;
DATA L_MEDS;
INFILE DATALINES MISSOVER firstobs=4;
/*KEEP THE UNREAD DATA IN FOR A WHILE - MAYBE WE'LL GET MORE VARIABLES*/
input @1 name           $char8.
        @10 LEFT_LINE   1.
        @13 L_OB_CD     $CHAR4.
        @19 gender      1.
        @22 INF_con_frm $CHAR3.
        @27 VNUM        1.
        @32 AM_PM       $CHAR2.
        @34 EXER_TM     TIME8.
        @44 LAB         $CHAR7.       ;
format EXER_TM time6.2;
datalines;
name   LEFT_LINE sex ICF VNUM AM/PM TIME   LAB
         1         2         3         4         5
12345678901234567890123456789012345678901234567890
_1_1*1M  1  L1_1  1  YES  1    AM    2:20  ACME
_2_2*1M  2  L2_1  1  YES  1    AM    2:20  ACME
_2_2*1M  3  L2_2  1  YES  1    PM    2:40  GENERIC
_3_1*2M  4  L3_1  2  YES  1    AM    2:10  GENERIC
_4_2*3M  5  L4_1  2  YES  1    PM    2:19  ACE
_4_2*3M  6  L4_2  1       1    AM    1:58  ACE

_5_3*2M  7  L5_1  1       1    PM    2:02  ACME
_5_3*2M  8  L5_2  1  YES  1    AM    2:50  ACME

_5_3*2M  9  L5_3  1  YES  2    PM    2:02  ACME
;

RUN;
PROC SORT DATA=L_MEDS;
BY NAME LEFT_LINE;
RUN;


DATA R_RUN_TIMES; /*SUBJECTS A HALF MILE AND RUN TWICE A DAY*/
INFILE DATALINES MISSOVER FIRSTOBS=4;
input @1  name       $char8.
      @11 RIGHT_LINE 1.

      @14 R_OB_CD     $CHAR4.

      @21 RAIN_YN    1.

      @26 RUN_ALONE  $CHAR3.
      @33 SPLITS_YN  $CHAR3.
      @37 ELAPS_TM   TIME10.
      @50 TRACK      $CHAR12.
      @64 WARMUP     $CHAR3.
;
datalines;
NAME   RIGHT_LINE RAIN  ALONE? SPLITS   ELAPS_TM  TRACK      WARMUP
         1         2         3         4         5         6         7
1234567890123456789012345678901234567890123456789012345678901234567890
_1_1*1M   1  R1_1   1     NO     NO      2:20     mi/4 CINDER  YES
_2_2*1M   2  R2_1   1     NO     YES     2:40     mi/4 TARTAN  YES
_3_1*2M   3  R3_1   2     YES    NO      2:19     mi/4 TARTAN  NO
_3_1*2M   4  R3_2   2     YES    NO      2:19     mi/4 TARTAN  NO
_4_2*3M   5  R4_1   0     NO     NO      1:58     1/8 MI       NO
_4_2*3M   6  R4_2   0     NO     NO      2:02     1/8 MI       NO
_4_2*3M   7  R4_3   0     NO     NO      2:02     1/8 MI       NO
_5_3*2M   8  R5_1   0     NO     NO      2:02     1/8 MI       YES
_5_3*2M   9  R5_2   1     NO     YES     2:50     mi/4 TARTAN  YES
;
RUN;


PROC SORT DATA=R_RUN_TIMES;
BY NAME RIGHT_LINE;
RUN;

*1 use a where r=0 to stop processing when we fail to read from r; *r always is 1;
* use a watch on to jump to the next value of name - then step through;
*mention that one ds has 8 obs and another has 9 then examine for _n_ ;
OPTIONS LS=120;
DATA BOTH1 ;
MERGE L_MEDS      (IN=M ) END=ENDMED
      R_RUN_TIMES (IN=R ) END=ENDRUN;
BY NAME;
PERM_M=m;
PERM_r=r;
P_ENDMED=ENDMED;
P_ENDRUN=ENDRUN;
DUMMY="XX";
RUN;


PROC PRINT DATA=BOTH1;
var    name L_OB_CD R_OB_CD LEFT_LINE RIGHT_LINE  PERM_r    PERM_M  P_ENDMED   P_ENDRUN TRACK;
RUN;

*****************************************************************************;
**                                                                         **;
**                    SHOW ISSUES WITH LAG VARAIBLES                       **;
**                                                                         **;
*****************************************************************************;
data oops;
infile datalines missover firstobs=3 ;
input  @1 name $char3. @5 vnum 1. @8 pulse 2. @12 TST_CTRL $CHAR1.;
datalines;
         1         2
12345678901234567890
bob 0  72  T
bob 1  72  T
bob 2  74  T
bob 3  75  T
SUE 0  72  C
SUE 1  72  C
SUE 2  74  C
SUE 3  75  C
Lun 0  72  T
Lun 1  72  T
Lun 2  74  T
Lun 3  75  T
;
run;

proc sort data=oops;
by name vnum;
run;

proc print data=oops;
run;

data oops2;
set oops;
by name vnum;
if first.name =0 then old=lag(pulse);
run;


proc print data=oops2;
run;

*****************************************************************************;
**                                                                         **;
**                    SHOW END=EOF AND WHERE VS IF                         **;
**                                                                         **;
*****************************************************************************;
data oops2;
infile datalines missover firstobs=3 ;
input  @1 name $char3. @5 vnum 1. @8 pulse 2. @12 TST_CTRL $CHAR1.;
datalines;
         1         2
12345678901234567890
bob 0  72  T
bob 1  72  T
bob 2  74  T
bob 3  75  T
SUE 0  72  C
SUE 1  72  C
SUE 2  74  C
SUE 3  75  C
Lun 0  72  T
Lun 1  72  T
Lun 2  74  T
Lun 3  75  T
;
run;

proc sort data=oops2;
by name vnum;
run;

proc print data=oops2;
run;


*USE A DATA STEP TO COUNT THE NUBER OF OBS;
DATA _NULL_/debug;
SET OOPS2 END=EOF;
BY  name vnum;
stopper="here";
*IF upcase(TST_CTRL)="C";
where upcase(TST_CTRL)="C";

counter+1;
if EOF=1 then
   do;
     put "this is the end and we had " counter "observations";
   end;
run;





*****************************************************************************;
**                                                                         **;
** MAYBE  SHOW BOB VIRGILS COOL WHERE ON PAGE 87 OF NESUG 93               **;
**                                                                         **;
*****************************************************************************;




*****************************************************************************;
**                                                                         **;
**  maybe  SHOW attempts to use macro variables in DSD                     **;
**                                                                         **;
*****************************************************************************;
OPTIONS MPRINT MLOGIC SYMBOLGEN;
%LET TRACK=mi/4 TARTAN;
%LET TRACK=1/8 MI;


OPTIONS LS=120;*THIS RUNS AND PRODUCES OUTPUT;;
DATA BOTH2 /DEBUG;
MERGE L_MEDS      (IN=M ) END=ENDMED
      R_RUN_TIMES (IN=R WHERE=( TRACK="&TRACK")) END=ENDRUN;
BY NAME;
MACRO_IS="&TRACK"; *JUST A WAY TO LOOK AT THE MACRO VARIABLE;
PERM_M=m;
PERM_r=r;
P_ENDMED=ENDMED;
P_ENDRUN=ENDRUN;

DUMMY="XX";
  TRACK_COUNT+1;
IF ENDRUN THEN PUT "SUBJECTS USED &TRACK TRACKS " TRACK_COUNT " TIMES";

RUN;




OPTIONS LS=120;*THE IF STATEMENT DELETES THE OBS WHEN ENDRUN =1;
DATA BOTH3 /DEBUG;
MERGE L_MEDS      (IN=M ) END=ENDMED
      R_RUN_TIMES (IN=R ) END=ENDRUN;
BY NAME;
MACRO_IS="&TRACK"; *JUST A WAY TO LOOK AT THE MACRO VARIABLE;
IF TRACK=: "PUT(SYMGET('TRACK')";
PERM_M=m;
PERM_r=r;
P_ENDMED=ENDMED;
P_ENDRUN=ENDRUN;

DUMMY="A STOP POINT";
  TRACK_COUNT+1;

IF ENDRUN THEN
       DO;
       PUT;PUT;
       PUT "SUBJECTS USED &TRACK TRACKS " TRACK_COUNT " TIMES";
       END;
DUMMY2="A STOP POINT AFTER THE COMMAND THAT INTERESTS ME";
RUN;




*****************************************************************************;
**                                                                         **;
**  SHOW storing of results of macro execution in a file                   **;
**                                                                         **;
*****************************************************************************;
options mlogic mprint symbolgen;

options mprint reservedb1;
filename mac_list 'c:\temp\lookSAS.txt';
%macro Sub_set(region=2);
  proc sql;
    select region
          ,COUNT(*)
          into :regnLst separated by '' , :junkLst separated by ','
    from non_profit
    GROUP BY REGION
    ORDER BY REGION;
  quit;

%let regnLst=&regnLst


 %put The macro vaiable regnLst evaluates to  &regnLst with counts of &JunkLst;

 %* ONLY RUN FOR VALID ENTRIES;

 %if %index(&regnLst,&region) LE 0 %then
   %do;
        %put;
        %put **************************************************;
        %put the value entered,  &region  is not a valid region;
        %put valid values are: &regnLst                        ;
        %put **************************************************;
        %put ;
   %end;
 %else %if %index(&regnLst,&region) >0 %then
   %do;
       data sub_set;
        set non_profit(where=(region=&region));
       run;

       PROC PRINT DATA=SUB_SET;
       TITLE "WHERE REGION=  &REGION";
       RUN;

       TITLE;
       RUN;
   %end;

*   data _null_;
*   closefile mac_list;
*   run;

%mend sub_set;

%sub_set(region=1);


x fclose(c:\temp\lookSAS.txt);
run;
*****************************************************************************;
**                                                                         **;
**  This is the section for introducing the Datasets                       **;
**                                                                         **;
*****************************************************************************;
OPTIONS NOCENTER;
proc format;
value born_in 1="NE"
              2="SE"
              3="NW"
              4="SW"
              5="Intnl";
run;


data humans (sortedby=name);;
infile datalines missover firstobs=2;
input @1 name $char8. @10 time_W_co @15 sex $char1. @18 job $char4.  @25 line_no;
datalines;
123456789012345678901234567890
Art      1    M  Stat   1
Brent    6    M  Stat   2
Cathy    6    F  Stat   3
Debbie   5    F  Stat   4
Jen      13   F  Stat   5
Russ     2    M  Prog   6
Saad     3    M  Prog   7
Tom      6    M  Stat   8
Zim      6    M  Stat   9
;
run;


data pets (sortedby=name);
infile datalines missover firstobs=2;
input @1 name $char8. @9 repeat  @15 type $char3.  @20 Pet_nm  $char8.  ;
datalines;
123456789012345678901234567890
Art     1     Dog  Catcher
Brent   1     N
Cathy   1     Dog  R.A.
Debbie  1     Dog  Dusty
Jen     1     Cat  Princess
Jen     2     Cat  Gabbie
Jen     3     Cat  India
Mary    1     Dog  Rao
Saad    1     N
;
run;





















*****************************************************************************;
*0    Step return jump go quit                                             ;
*****************************************************************************;

*Snippet 0A  Step return jump go quit    ;
*****************************************************************************;
**                                                                         **;
**  Example of a how knowledge of the PDV is essential                     **;
**  There are no error messages, just a list of values that you must       **;
** interpret according to your expectations                                **;
** use the f4 key and binding to keys                                      **;
** look at when num-h is created- before the set statement                 **;
**                                                                         **;
*****************************************************************************;

data sample/debug; /*focus on _N_, values in the PDV and num_h*/
   do obsnum=1 to num_h by 2;
      set humans point=obsnum nobs=num_h;
      if _error_ then abort;

      output;
   end;
   stop;
run;







*****************************************************************************;
*1    Examine, list and describe                                             ;
*****************************************************************************;

*Snippet 1A Examine, list and describe;
*****************************************************************************;
**                                                                         **;
**  Example of a how knowledge of the PDV is essential                     **;
**  There are no error messages, just a list of values that you must       **;
** interpret according to your expectations                                **;
** use the f4 key and binding to keys                                      **;
** look at when num-h is created- before the set statement                 **;
**                                                                         **;
*****************************************************************************;
*one way to select a subset of the data - use pointer control;
*use exhamine list and describe commands;
data sample/debug; /*focus on _N_, values in the PDV and num_h*/
   do obsnum=1 to num_h by 2;
      set humans point=obsnum nobs=num_h;
      if _error_ then abort;
      output;
   end;
   stop;
run;

*Snippet 1B Examine, list and describe;
*****************************************************************************;
**                                                                         **;
**  Danger of recoding in a one to many merge                              **;
**  see the firs. and last. variables in a t of values that you must       **;
** interpret according to your expectations                                **;
** use the f4 key and binding to keys                                      **;
** look at when num-h is created- before the set statement                 **;
**                                                                         **;
*****************************************************************************;
*the danger of recoding in a one to many merge - first. and last. variables;
*use jump to skip the calculation of time _w_co;
data matching/debug;
 merge humans(in=h) pets(in=p);
   *stop_pt=1;
   by name;
   time_W_co=time_W_co*12;
   stop_pt=1;
run;

proc print;
run;


 *Snippet 1C Examine, list and describe;
*****************************************************************************;
**                                                                         **;
**  Look at the input buffer - not just the PDV                            **;
**  list I, b W _all_                                                      **;
**  notice that the input buffer contains Brent                            **;
**         but the variable name only contains rent                        **;
** also see the list command as a tool for managing break and watch points **;
** ISSUE THE DESCRIBE _ALL_ COMMAND  -Does show formats - see someday      **;
*****************************************************************************;

data pets (sortedby=name)/debug;
infile datalines missover firstobs=2;
input @2 name $char8. @9 repeat 4.2 @15 type $char3.  @20 Pet_nm  $char8.
                      @9 someday ;
format someday date9.;
datalines;
123456789012345678901234567890
 Art    1     Dog  Catcher
Brent   1     N
Cathy   1     Dog  R.A.
Debbie  1     Dog  Dusty
Jen     1     Cat  Princess
Jen     2     Cat  Gabbie
Jen     3     Cat  India
Mary    1     Dog  Rao
Saad    1     N
;
run;

proc print;
run;

 *Snippet 1D Examine, list and describe;
*****************************************************************************;
**  use this to show that we can appply formats to dates                   **;
** USE THIS TO SHOW EXAMINE, SHOWING DATES WITH FORMATS, FORMATS FOR NUMBER**;
** use the f4 key and binding to keys                                      **;
** USE EXAMINE ON THIS_                                                    **;
**                                                                         **;
*****************************************************************************;
**keep on data step vs set statement;
data left;
infIle datalines missover firstobs=3;
input @1 name $char4. @8 gender 1.  @10 enroll DATE9.;
THIS_DATE=TODAY();
ENROLLED=THIS_DATE-ENROLL;
datalines;
         1         2         3         4         5
12345678901234567890123456789012345678901234567890
Sai    1 01JAN2003
Yung   1 05FEB2002
Yong   1 12MAR2002
ODD    3 22MAR2004
Sue    2 22SEP2001
Bob    1 18AUG1998
RUSS   1 19JUN1997
LIJI   1 30SEP1995
MUSA   1 20JUL2001
DEB    2 11MAR2002
;
RUN;

*SNIPPET  1E_;
*****************************************************************************;
**  for independent investigation - outside of session                     **;
**  Example of a KEEP on a data statement vs KEEP on a set                 **;
**                                                                         **;
** USE THIS TO SHOW EXAMINE, SHOWING DATES WITH FORMATS, FORMATS FOR NUMBER**;
** use the f4 key and binding to keys                                      **;
** USE EXAMINE ON THIS_                                                    **;
**                                                                         **;
*****************************************************************************;
**SHOW A KEEP ON THE INPUT VS A KEEP ON THE OUTPUT DATA SET;
data show_keep1(keep=F_NAME wks_enr) /debug;
set left (RENAME =(NAME=F_NAME));
wks_enr=enrolled/7;
run;

PROC PRINT;
TITLE "WE HAD MANY VARIABOLES ON THE pdv , BUT FEW IN OUTPUT DATASET";
RUN;

** SNIPPET FOR INDEPENDENT EXPLORATION;
*CODE BELOW WILL CAUSE AN ERROR -  RENAMED VARIBLE IS ON THE pdv AND CAN NOT BE KEPT ON OUTPUT;
data show_keep2(keep=name wks_enr) /debug;
set left(keep=name wks_enr RENAME =(NAME=F_NAME));
wks_enr=enrolled/7;
run;




*****************************************************************************;
*    BREAK, Delete Watch Trace                                               ;
*****************************************************************************;

*Snippet 2A   BREAK, Delete Watch Trace ;
*****************************************************************************;
** Set break point                                                         **;
**  Look at the input buffer - not just the PDV                            **;
**  list I, b W _all_                                                      **;
**  notice that the input buffer contains Brent                            **;
**         but the variable name only contains rent                        **;
** also see the list command as a tool for managing break and watch points **;
** ISSUE THE DESCRIBE _ALL_ COMMAND  -Does show formats - see someday      **;
*****************************************************************************;
data pets (sortedby=name)/debug;
infile datalines missover firstobs=2;
input @2 name $char8. @9 repeat 4.2 @15 type $char3.  @20 Pet_nm  $char8.
                      @9 someday ;
format someday date9.;
datalines;
123456789012345678901234567890
 Art    1     Dog  Catcher
Brent   1     N
Cathy   1     Dog  R.A.
Debbie  1     Dog  Dusty
Jen     1     Cat  Princess
Jen     2     Cat  Gabbie
Jen     3     Cat  India
Mary    1     Dog  Rao
Saad    1     N
;
run;



*Snippet 2B   BREAK, Delete Watch Trace ;
*use fo debugger for a do loop;
*break when I = exit condition;
*divide the max by an integer and use in the break;
*put in a non-ececutable line;
*break with an in to break just before / after the cutpoints;
options nocenter;
data non_profit /debug;
infile datalines missover firstobs=3;
length age_grp $ 5;
input @1 name     $char8.
      @11 gender  $char1.
      @13 age1    2.0
      @13 age2    2.0
      @17 From    $char8.
      @25 Q1_hrs  3.
      @30 Q2_hrs  3.
      @35 region  1.;
total= Q1_hrs + Q2_hrs;
do i=1 to age1;
  stopper="here";
  *YOU CAN ALSO DIVIDE THE MAX BY AN INTEGER AND USE IN THE BREAK;
  if i LE 12
         then age_grp ="Child";
  else if i GT 12 and i LT 20
         then age_grp ="Teen";
  else if i GE 21
         then age_grp ="Adult";
end;
pct_1= Q1_hrs  /total;
pct_2= Q1_hrs  /total;
datalines;
         1         2         3         4
1234567890123456789012345678901234567890
Sue      F  10  Florida 017  022  2
Mike     M  12  Conn    027  042  1
Erin     F  13 Ireland  021  012  5
Ya-Ching F  20  China   017  024  5
Ann      F  21  Mass    022  014  1
Jeff     M  45 Calif    078  099  4
Yuan     F  27  Nevada  026  046  4
Suna     F  31  India   017  011  5
Eric     M  45  Oregon  041  023  3
;
run;

proc print data=non_profit;
run;





*****************************************************************************;
*****************************************************************************;
*****************************************************************************;
*****************************************************************************;
**                                                                         **;
**  PRACTICE ON EXAMPLES                                                   **;
**                                                                         **;
*****************************************************************************;
*****************************************************************************;
*****************************************************************************;
*****************************************************************************;

*****************************************************************************;
**                                                                         **;
**  AS A PRELIMINARY - STORE AN ABBREVIATION IN A KEY                      **;
**                                                                         **;
*****************************************************************************;



*STORE A MACRO IN A KEY
/*  DSD STEP 1; DSD EXAMINE _ALL;  */











*Snippet EXAMPLE: A   COLLECT THE EVLAUATED MACRO CODE;
*****************************************************************************;
**                                                                         **;
**  COLLECT HOW A MACRO EVALUATES AND STORE IN A TEXT FILE                 **;
**                                                                         **;
*****************************************************************************;

%MACRO series;
data new;
total= %do i=6 %to 12;
&i %str(+) %end;  0 ;
run;

proc print data=&dset;
run;

proc means;
run;

%MEND series;


options mprint mfile;
filename mprint "c:\temp\series_txt.txt";
%series;




*Snippet EXAMPLE: B   COLLECT THE EVLAUATED MACRO CODE;
*****************************************************************************;
**                                                                         **;
**  Example of if _N_=1 then set statement                                 **;
**                                                                         **;
** do this in steps, first look at data no_read                            **;
**     use the f4 key and binding to keys                                  **;
** USE THIS, WITH LOOK,  TO SHOW THAT SET LAST IS VALUED BEFORE THE SET    **;
**     SHOW THAT LAST IS NOT OUTPUT TO THE DATA SET & THEN APPLY THE KEEP  **;
**     SOW AUTOMATIC RETAIN FOR VARIABLES FROM A SET STATEMENT             **;
*****************************************************************************;

data no_read/debug;
*data no_read(keep=obs_perm) /debug;
*look="look";
if _N_ = 0 then set left nobs=last;
obs_perm=last;
run;

proc print;
run;

data show_N_(keep=name wks_enr) /debug;
if _n_=1 then set no_read;
set left;
wks_enr=enrolled/7;
run;


*Snippet EXAMPLE: C   COLLECT THE EVLAUATED MACRO CODE;
*****************************************************************************;
**    NO RETAIN IF YOU USE AN INPUT STATEMENT                              **;
**  This is from the SAS help file                                         **;
**  This illustrates how there is NO retain for a input statement          **;
**  the problem show up when _n_=2                                         **;
**                                                                         **;
** USE THIS TO SHOW:                                                       **;
**   BREAKS & DELETE BREAKS, EXAMINE ALL                                   **;
**   SET A WATCH ON TYPE SO YOU CAN CHECK THE IF STATEMENT                 **;
**   SET A BREAK WHEN TOUR CHANGES AS AN ILLUSTRATION                      **;
**   us the f4 keys and binding to keys                                    **;
*****************************************************************************;
/* first execution */
data tours (drop=type);
*RETAIN TOUR;
infile datalines missover firstobs=3;
   input @1 type $ @;
   if type='H' then do;
      input @3 Tour $20.;
      return;
      end;
   else if type='P' then do;
      input @3 Name $10. Age 2. +1 Sex $1.;
      output;
      end;
   datalines;
         1         2         3         4         5
12345678901234567890123456789012345678901234567890
H Tour 101
P Mary E    21 F
P George S  45 M
P Susan K    3 F
H Tour 102
P Adelle S  79 M
P Walter P  55 M
P Fran I    63 F
;

proc print data=tours;
   title 'Tour List';
run;



*****************************************************************************;
**                   MERGE EXAMPLE                                         **;
** one to one, two to 1, one to two, three to two and two to three merge   **;
**                                                                         **;
** This is mostly a view of the SAS merge,and to see in=variables          **;
** use breaks examine                                                      **;
** break where r=0                                                         **;
**   use f4 and keys                                                       **;
*****************************************************************************;
DATA L_MEDS;
INFILE DATALINES MISSOVER firstobs=4;
/*KEEP THE UNREAD DATA IN FOR A WHILE - MAYBE WE'LL GET MORE VARIABLES*/
input @1 name           $char8.
        @10 LEFT_LINE   1.
        @13 L_OB_CD     $CHAR4.
        @19 gender      1.
        @22 INF_con_frm $CHAR3.
        @27 VNUM        1.
        @32 AM_PM       $CHAR2.
        @34 EXER_TM     TIME8.
        @44 LAB         $CHAR7.       ;
format EXER_TM time6.2;
datalines;
name   LEFT_LINE sex ICF VNUM AM/PM TIME   LAB
         1         2         3         4         5
12345678901234567890123456789012345678901234567890
_1_1*1M  1  L1_1  1  YES  1    AM    2:20  ACME
_2_2*1M  2  L2_1  1  YES  1    AM    2:20  ACME
_2_2*1M  3  L2_2  1  YES  1    PM    2:40  GENERIC
_3_1*2M  4  L3_1  2  YES  1    AM    2:10  GENERIC
_4_2*3M  5  L4_1  2  YES  1    PM    2:19  ACE
_4_2*3M  6  L4_2  1       1    AM    1:58  ACE
_5_3*2M  7  L5_1  1       1    PM    2:02  ACME
_5_3*2M  8  L5_2  1  YES  1    AM    2:50  ACME
_5_3*2M  9  L5_3  1  YES  2    PM    2:02  ACME
;
RUN;
PROC SORT DATA=L_MEDS;
BY NAME LEFT_LINE;
RUN;


DATA R_RUN_TIMES; /*SUBJECTS A HALF MILE AND RUN TWICE A DAY*/
INFILE DATALINES MISSOVER FIRSTOBS=4;
input @1  name       $char8.
      @11 RIGHT_LINE 1.
      @14 R_OB_CD     $CHAR4.
      @21 RAIN_YN    1.
      @26 RUN_ALONE  $CHAR3.
      @33 SPLITS_YN  $CHAR3.
      @37 ELAPS_TM   TIME10.
      @50 TRACK      $CHAR12.
      @64 WARMUP     $CHAR3.
;
datalines;
NAME   RIGHT_LINE RAIN  ALONE? SPLITS   ELAPS_TM  TRACK      WARMUP
         1         2         3         4         5         6         7
1234567890123456789012345678901234567890123456789012345678901234567890
_1_1*1M   1  R1_1   1     NO     NO      2:20     mi/4 CINDER  YES
_2_2*1M   2  R2_1   1     NO     YES     2:40     mi/4 TARTAN  YES
_3_1*2M   3  R3_1   2     YES    NO      2:19     mi/4 TARTAN  NO
_3_1*2M   4  R3_2   2     YES    NO      2:19     mi/4 TARTAN  NO
_4_2*3M   5  R4_1   0     NO     NO      1:58     1/8 MI       NO
_4_2*3M   6  R4_2   0     NO     NO      2:02     1/8 MI       NO
_4_2*3M   7  R4_3   0     NO     NO      2:02     1/8 MI       NO
_5_3*2M   8  R5_1   0     NO     NO      2:02     1/8 MI       YES
_5_3*2M   9  R5_2   1     NO     YES     2:50     mi/4 TARTAN  YES
;
RUN;


PROC SORT DATA=R_RUN_TIMES;
BY NAME RIGHT_LINE;
RUN;

*1 use a where r=0 to stop processing when we fail to read from r; *r always is 1;
* use a watch on to jump to the next value of name - then step through;
*mention that one ds has 8 obs and another has 9 then examine for _n_ ;
OPTIONS LS=120;
DATA BOTH1 ;
MERGE L_MEDS      (IN=M ) END=ENDMED
      R_RUN_TIMES (IN=R ) END=ENDRUN;
BY NAME;
PERM_M=m;
PERM_r=r;
P_ENDMED=ENDMED;
P_ENDRUN=ENDRUN;
DUMMY="XX";
RUN;


PROC PRINT DATA=BOTH1;
var    name L_OB_CD R_OB_CD LEFT_LINE RIGHT_LINE  PERM_r    PERM_M  P_ENDMED   P_ENDRUN TRACK;
RUN;

*****************************************************************************;
**                                                                         **;
**                    SHOW ISSUES WITH LAG VARAIBLES                       **;
**                                                                         **;
*****************************************************************************;
data oops;
infile datalines missover firstobs=3 ;
input  @1 name $char3. @5 vnum 1. @8 pulse 2. @12 TST_CTRL $CHAR1.;
datalines;
         1         2
12345678901234567890
bob 0  72  T
bob 1  72  T
bob 2  74  T
bob 3  75  T
SUE 0  72  C
SUE 1  72  C
SUE 2  74  C
SUE 3  75  C
Lun 0  72  T
Lun 1  72  T
Lun 2  74  T
Lun 3  75  T
;
run;

proc sort data=oops;
by name vnum;
run;

proc print data=oops;
run;

data oops2;
set oops;
by name vnum;
if first.name =0 then old=lag(pulse);
run;


proc print data=oops2;
run;

*****************************************************************************;
**                                                                         **;
**                    SHOW END=EOF AND WHERE VS IF                         **;
**                                                                         **;
*****************************************************************************;
data oops2;
infile datalines missover firstobs=3 ;
input  @1 name $char3. @5 vnum 1. @8 pulse 2. @12 TST_CTRL $CHAR1.;
datalines;
         1         2
12345678901234567890
bob 0  72  T
bob 1  72  T
bob 2  74  T
bob 3  75  T
SUE 0  72  C
SUE 1  72  C
SUE 2  74  C
SUE 3  75  C
Lun 0  72  T
Lun 1  72  T
Lun 2  74  T
Lun 3  75  T
;
run;

proc sort data=oops2;
by name vnum;
run;

proc print data=oops2;
run;


*USE A DATA STEP TO COUNT THE NUBER OF OBS;
DATA _NULL_/debug;
SET OOPS2 END=EOF;
BY  name vnum;
stopper="here";
*IF upcase(TST_CTRL)="C";
where upcase(TST_CTRL)="C";

counter+1;
if EOF=1 then
   do;
     put "this is the end and we had " counter "observations";
   end;
run;





*****************************************************************************;
**                                                                         **;
** MAYBE  SHOW BOB VIRGILS COOL WHERE ON PAGE 87 OF NESUG 93               **;
**                                                                         **;
*****************************************************************************;




*****************************************************************************;
**                                                                         **;
**  maybe  SHOW attempts to use macro variables in DSD                     **;
**                                                                         **;
*****************************************************************************;
OPTIONS MPRINT MLOGIC SYMBOLGEN;
%LET TRACK=mi/4 TARTAN;
%LET TRACK=1/8 MI;


OPTIONS LS=120;*THIS RUNS AND PRODUCES OUTPUT;;
DATA BOTH2 /DEBUG;
MERGE L_MEDS      (IN=M ) END=ENDMED
      R_RUN_TIMES (IN=R WHERE=( TRACK="&TRACK")) END=ENDRUN;
BY NAME;
MACRO_IS="&TRACK"; *JUST A WAY TO LOOK AT THE MACRO VARIABLE;
PERM_M=m;
PERM_r=r;
P_ENDMED=ENDMED;
P_ENDRUN=ENDRUN;

DUMMY="XX";
  TRACK_COUNT+1;
IF ENDRUN THEN PUT "SUBJECTS USED &TRACK TRACKS " TRACK_COUNT " TIMES";

RUN;




OPTIONS LS=120;*THE IF STATEMENT DELETES THE OBS WHEN ENDRUN =1;
DATA BOTH3 /DEBUG;
MERGE L_MEDS      (IN=M ) END=ENDMED
      R_RUN_TIMES (IN=R ) END=ENDRUN;
BY NAME;
MACRO_IS="&TRACK"; *JUST A WAY TO LOOK AT THE MACRO VARIABLE;
IF TRACK=: "PUT(SYMGET('TRACK')";
PERM_M=m;
PERM_r=r;
P_ENDMED=ENDMED;
P_ENDRUN=ENDRUN;

DUMMY="A STOP POINT";
  TRACK_COUNT+1;

IF ENDRUN THEN
       DO;
       PUT;PUT;
       PUT "SUBJECTS USED &TRACK TRACKS " TRACK_COUNT " TIMES";
       END;
DUMMY2="A STOP POINT AFTER THE COMMAND THAT INTERESTS ME";
RUN;




*****************************************************************************;
**                                                                         **;
**  SHOW storing of results of macro execution in a file                   **;
**                                                                         **;
*****************************************************************************;
options mlogic mprint symbolgen;

options mprint reservedb1;
filename mac_list 'c:\temp\lookSAS.txt';
%macro Sub_set(region=2);
  proc sql;
    select region
          ,COUNT(*)
          into :regnLst separated by '' , :junkLst separated by ','
    from non_profit
    GROUP BY REGION
    ORDER BY REGION;
  quit;

%let regnLst=&regnLst


 %put The macro vaiable regnLst evaluates to  &regnLst with counts of &JunkLst;

 %* ONLY RUN FOR VALID ENTRIES;

 %if %index(&regnLst,&region) LE 0 %then
   %do;
        %put;
        %put **************************************************;
        %put the value entered,  &region  is not a valid region;
        %put valid values are: &regnLst                        ;
        %put **************************************************;
        %put ;
   %end;
 %else %if %index(&regnLst,&region) >0 %then
   %do;
       data sub_set;
        set non_profit(where=(region=&region));
       run;

       PROC PRINT DATA=SUB_SET;
       TITLE "WHERE REGION=  &REGION";
       RUN;

       TITLE;
       RUN;
   %end;

*   data _null_;
*   closefile mac_list;
*   run;

%mend sub_set;

%sub_set(region=1);


x fclose(c:\temp\lookSAS.txt);
run;











































































%MACRO series;
data new;
total= %do i=6 %to 12;
&i %str(+) %end;  0 ;
run;

proc print data=&dset;
run;

proc means;
run;

%MEND series;


options mprint mfile;
filename mprint "c:\temp\series_txt.txt";
%series;
options nomfile;
