Search notes:

SAS: code snippets

list-of-available-tables.sas

%let ora_user     = rene;
%let ora_password = secret_garden;
%let ora_server   = ora.test.renenyffenegger.ch;

libname tq84_ora
   oracle 
   user                     = &ora_user
   password                 = &ora_password
   path                     = &ora_server
   sql_functions            = all
   db_length_semantics_byte = no;


proc sql;
  create table tq84_available_tables as
  select *
  from   dictionary.tables
  where  libname = 'TQ84_ORA';
quit;

proc show data=tq84_available_tables;
run;
Github repository about-SAS, path: /programming/dictionary/dictionary/oracle/list-of-available-tables.sas

extfiles.sas

proc sql;
  describe table dictionary.extfiles;
quit;

/*
create table DICTIONARY.EXTFILES
  (
   fileref char(8) label='Fileref',
   xpath char(1024) label='Pathname',
   xengine char(8) label='Engine Name',
   modate num format=DATETIME informat=DATETIME label='Date Modified',
   filesize num label='Size of File',
   level num label='File Concatenation Level',
   directory char(3) label='Directory?',
   exists char(3) label='Exists?',
   temporary char(3) label='Temporary?'
  );
*/
Github repository about-SAS, path: /programming/dictionary/extfiles.sas

styles.sas

proc sql;
  describe table dictionary.styles;
quit;


/*
create table DICTIONARY.STYLES
  (
   libname char(8) label='Library Name',
   memname char(32) label='Member Name',
   style char(32) label='Style Name',
   crdate num format=DATETIME informat=DATETIME label='Date Created'
  );
*/
Github repository about-SAS, path: /programming/dictionary/styles.sas

titles.sas

proc sql;
  describe table dictionary.titles;
quit;

/*
create table DICTIONARY.TITLES
  (
   type char(1) label='Title Location',
   number num label='Title Number',
   text char(256) label='Title Text'
  );
*/
Github repository about-SAS, path: /programming/dictionary/titles.sas

show-indexes-in-library-member.sas

proc sql;
  select
    indxname,
    name    ,  /* column name */
    unique  ,
    idxusage,  /* SIMPLE, COMPOSITE */
    indxpos    /* position of column in concatenated key */
  from
    dictionary.indexes
  where
    libname = 'TQ84_LIB' and
    memname = 'TQ84_MEMBER'
  order by
    indxname,
    indxpos;
quit;
Github repository about-SAS, path: /programming/dictionary/indexes/show-indexes-in-library-member.sas

describe.sas

proc sql;
  describe table dictionary.indexes;
quit;

/*
create table DICTIONARY.INDEXES
  (
   libname char(8) label='Library Name',
   memname char(32) label='Member Name',
   memtype char(8) label='Member Type',
   name char(32) label='Column Name',
   idxusage char(9) label='Column Index Type',
   indxname char(32) label='Index Name',
   indxpos num label='Position of Column in Concatenated Key',
   nomiss char(3) label='Nomiss Option',
   unique char(3) label='Unique Option'
  );
*/
Github repository about-SAS, path: /programming/dictionary/indexes/describe.sas

views.sas

proc sql;
  describe table dictionary.views;
quit;


/*
create table DICTIONARY.VIEWS
  (
   libname char(8) label='Library Name',
   memname char(32) label='Member Name',
   memtype char(8) label='Member Type',
   engine char(8) label='Engine Name'
  );
*/
Github repository about-SAS, path: /programming/dictionary/views.sas

remember.sas

proc sql;
  describe table dictionary.remember;
quit;

/*
create table DICTIONARY.REMEMBER
  (
   libname char(8) label='Library Name',
   memname char(32) label='Member Name',
   offset num label='Offset into Text Remembered',
   rtext char(200) label='Text Remembered',
   pw char(8) label='Password'
  );
*/
Github repository about-SAS, path: /programming/dictionary/remember.sas

constraint_table_usage.sas

proc sql;
  describe table dictionary.constraint_table_usage;
quit;

/*


create table DICTIONARY.CONSTRAINT_TABLE_USAGE
  (
   table_catalog char(8) label='Libname',
   table_schema char(8) label='Table Schema',
   table_name char(32) label='Table',
   constraint_catalog char(32) label='Constraint Catalog',
   constraint_schema char(8) label='Constraint Schema',
   constraint_name char(32) label='Constraint Name'
  );
  
*/
Github repository about-SAS, path: /programming/dictionary/constraint_table_usage.sas

describe.sas

proc sql;

  describe view sashelp.vallopt;

quit;
/*
SQL view SASHELP.VALLOPT is defined as:

        select *
          from DICTIONARY.OPTIONS
        union
        select *
          from DICTIONARY.GOPTIONS;
*/
Github repository about-SAS, path: /programming/libraries/SASHELP/vallopt/describe.sas

describe.sas

proc sql;

  describe view sashelp.vcolumn;

quit;

/*
SQL view SASHELP.VCOLUMN is defined as:

        select *
          from DICTIONARY.COLUMNS;
*/
Github repository about-SAS, path: /programming/libraries/SASHELP/vcolumn/describe.sas

select-all.sql

proc sql;

  select
    memname,
    memtype /* CATALOG, DATA, ITEMSTOR, MDDB, VIEW */
  from
    dictionary.members
  where
    libname = 'SASHELP'
  order by
    memtype,
    memname;

quit;
Github repository about-SAS, path: /programming/libraries/SASHELP/select-all.sql

comments.sas

data _null_;

/* Comments are either between
   slash-star and star-slash */

* or between * and semicolon;



%macro temporary_commented;

  A macro definition with any name (such
  as temporary_commented) can be used to
  comment a block of code

  /* foo bar baz */

%mend;

  put 'Hello world.';
run;
Github repository about-SAS, path: /programming/comments.sas

condition.sas

data _null_;
  array tq84_array(9);

  tq84_array(1) =  1;
  tq84_array(2) =  4;
  tq84_array(3) =  2;
  tq84_array(4) =  5;
  tq84_array(5) =  4;
  tq84_array(6) =  3;
  tq84_array(7) =  4;
  tq84_array(8) = 10;
  tq84_array(9) =  2;
  
  tq84_nof_elements_eq_4 = sum(
    tq84_array1 = 4,
    tq84_array2 = 4,
    tq84_array3 = 4,
    tq84_array4 = 4,
    tq84_array5 = 4,
    tq84_array6 = 4,
    tq84_array7 = 4,
    tq84_array8 = 4,
    tq84_array9 = 4
);

  put "Array contains " tq84_nof_elements_eq_4 " elements whose value is 4.";
run;
Github repository about-SAS, path: /programming/statements/sum/condition.sas

exclude-variable.sas

data tq84_one;

  infile datalines;

  length col_1 $10;
  length col_2 $10;
  length col_3 $10;

  input
    col_1
    col_2
    col_3
  ;

datalines;
x y z
one two three
foo bar baz
strawberry blackberry blueberry
;


data tq84_two;
  set tq84_one;

  drop col_2;   /* Exclude variable col_2 from output */
  col_4 = _N_;  /* Add new variable to output */

run;

proc print data=tq84_two;
run;
Github repository about-SAS, path: /programming/statements/drop/exclude-variable.sas

is-assigned.sas

data _null_;
  if libref("tq84_l") ne 0 then
     put "tq84_l is not assigned";
  else
     put "tq84_l is assigned";
run;

libname tq84_l "s:\Atrans\SASCC\tq84";

data _null_;
  if libref("tq84_l") ne 0 then
     put "tq84_l is not assigned";
  else
     put "tq84_l is assigned";
run;

libname tq84_l clear;
Github repository about-SAS, path: /programming/statements/libref/is-assigned.sas

if-then-stop.sas

data tq84_data;
  
  do number = 1 to 10;
     if number > 5 then stop;

     output;
  end;

run;

proc print data=tq84_data;
run;
Github repository about-SAS, path: /programming/statements/stop/if-then-stop.sas

if.sas

data _null_;

  a =  7;
  b =  6;
  c = 42;

  if a*b = 42 then
     put a " * " b " = " c;
  else
     put a " * " b " != " c;

run;

/* See also: ifc.sas */
Github repository about-SAS, path: /programming/statements/if.sas

simple-example.sas

data tq84_one;

  infile datalines;

  length col_2 $10;
  input
    col_1
    col_2
  ;

datalines;
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
;


data tq84_two;
  set tq84_one;

  /* Compare with subsetting if */
  where col_2 gt 's';
  
run;

proc print data=tq84_two;
run;
Github repository about-SAS, path: /programming/statements/where/simple-example.sas

access.readonly.sas

libname tq84_ora
   oracle 
   user            = &ora_user
   password        = &ora_password
   path            = &ora_server
   sql_functions   = all
   access          = readonly;
Github repository about-SAS, path: /programming/statements/libname/oracle/access.readonly.sas

create-table.sas

%let ora_user     = rene;
%let ora_password = secret_garden;
%let ora_server   = ora.test.renenyffenegger.ch;


libname tq84_ora
   oracle 
   user                     = &ora_user
   password                 = &ora_password
   path                     = &ora_server
   sql_functions            = all
   db_length_semantics_byte = no;


data tq84_stage;

  length spelled $20;

  input
    val
    spelled $
  ;

datalines;
1 one
2 two
3 three
4 four
5 five
42 forty-two
;


proc sql;
  create table
    tq84_ora.a_table_name
  as
    select * from tq84_stage;
quit;
Github repository about-SAS, path: /programming/statements/libname/oracle/create-table.sas

drop-all-variables-except.sas

data tq84_one;

  infile datalines;

  length col_1 $10;
  length col_2 $10;
  length col_3 $10;
  length col_4 $10;
  length col_5 $10;

  input
    col_1
    col_2
    col_3
    col_4
    col_5
  ;

datalines;
a b c d e
one two three four five
foo bar baz qux quux
morning noon afternoon evening night
;


data tq84_two;
  set tq84_one;

  keep col_2 col_4;   /* Drop all variables except col_2 and col_4 */
  
run;

proc print data=tq84_two;
run;
Github repository about-SAS, path: /programming/statements/keep/drop-all-variables-except.sas

variable-assignment.sas

data;

foo="bar";
%put foo;

run;
Github repository about-SAS, path: /programming/variable-assignment.sas

option: mprint

Show generated code:
/*
   With the mprint system option turned on, SAS will print
   the generated code into the log.
   
   This is useful for debugging purposes.
*/

options mprint;

%macro tq84_m(nof_obs, nof_attrs);
data tq84_data;

  drop obs;

  do obs=1 to &nof_obs;
      %do varno = 1 %to &nof_attrs;
          var_&varno = rand('norm');
      %end;
      output;
  end;

run;
%mend tq84_m;

%tq84_m(5, 3);
/*
MPRINT(TQ84_M):   data tq84_data;
MPRINT(TQ84_M):   drop obs;
MPRINT(TQ84_M):   do obs=1 to 5;
MPRINT(TQ84_M):   var_1 = rand('norm');
MPRINT(TQ84_M):   var_2 = rand('norm');
MPRINT(TQ84_M):   var_3 = rand('norm');
MPRINT(TQ84_M):   output;
MPRINT(TQ84_M):   end;
MPRINT(TQ84_M):   run;
*/
Github repository about-SAS, path: /programming/options/mprint/show-generated-code.sas

Show index usage in proc sql

/* Use msglevel=I to print index usage into log */
options msglevel=I;

libname tq84_sql 'p:\ath\to\some\directory';

proc datasets 
     library=tq84_sql
     kill;/* Delete all files in the library at once. */
run;

data tq84_sql.english_numbers;
  length num 4. txt $ 10;
  input  num txt;
datalines;
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
10 ten
run;


data tq84_sql.roman_numbers;
  length num 4. txt $ 10;
  input  num txt;
  /* Note the missing numbers 4, 7 and 8 */
datalines;
1 I
2 II
3 III
5 V
6 VI
9 IX
10 X
run;

%macro left_join_nums;
   proc sql;
     select
       en.num,
       en.txt,
       rm.txt
     from
       tq84_sql.english_numbers en left join
       tq84_sql.roman_numbers   rm on en.num = rm.num
     where
       en.num = 7;
   quit;
%mend left_join_nums;

%macro create_index_nums(tab);
   proc datasets library=tq84_sql;
     modify &tab;
     index create num / unique;
   run;
%mend create_index_nums;

%left_join_nums;

%create_index_nums(english_numbers);

%left_join_nums;
/* Because of 'options msglevel=I', log says:
   INFO: Index num selected for WHERE clause optimization.
*/

%create_index_nums(roman_numbers);

%left_join_nums;
Github repository about-SAS, path: /programming/options/msglevel/show-index-usage.sql

option: sastraceloc

options
  sastrace    = ',,,d'
  sastraceloc = file 'p:\ath\to\log.file' /* Specify file for log of sastrace */
;


libname tq84_ora
   oracle 
   user                     = &ora_user
   password                 = &ora_password
   path                     = &ora_server
   sql_functions            = all
   db_length_semantics_byte = no;


data dual;
  set tq84_ora.user_objects;
run;
Github repository about-SAS, path: /programming/options/sastraceloc/file.sas

option: source

Determine whether or not statements are written to the log:
/* Don't write statements to the log file: */
options nosource;

data _null_;
  put "foo";
run;

/* Write statements to the log file: */
options source;

data _null_;
  put "bar";
run;
Github repository about-SAS, path: /programming/options/source/write-statements-to-log.sas

option: obs

/*
   Limit result set to three records.

   Note: proc sql also has an "outobs=n" option.

*/
options obs=3;

proc sql;
  select * from sashelp.cars;
quit;
Github repository about-SAS, path: /programming/options/obs/sql-select.sas

matrix-histogram.sas

data xyz;
  call streaminit(280870);

  do x=1 to 100;
     y=(x/10) ** 2;
     z=x * (1+rand('unif')/3);
     output;
  end;
run;


ods graphics on;
proc corr
  data  = xyz
  plots = matrix(histogram);
run;
ods graphics off;
Github repository about-SAS, path: /programming/proc/corr/matrix-histogram.sas

random-sampling.sas

data tq84_data;

  length num     8
         txt  $ 10;

  input  num txt;

datalines;
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
10 ten
run;

proc sql outobs=5;

  select
    num,
    txt
  from
    tq84_data
  order by
    ranuni(280870);

quit;
Github repository about-SAS, path: /programming/proc/sql/random-sampling.sas

from-drop.sas

data tq84_data;

  length num     8
         en   $ 10
         gr   $ 10
         fr   $ 10;

  input  num en gr fr;

datalines;
1 one   eins un
2 two   zwei deux
3 three drei trois
4 four  vier quattre
5 five  fünf cinque
run;

proc sql;

  /* Select all columns except fr: */

  select *
  from   tq84_data(drop=fr);

quit;
Github repository about-SAS, path: /programming/proc/sql/from-drop.sas

find-unique-values.sas

data tq84_data;

  length id      8
         foo  $ 10
         bar  $ 10
         baz  $ 10;

  input  id foo bar baz;

datalines;
1 one      xxx    abc
2 two      abc    def
3 three    abc    .
4 four     xxx    ghi
5 five     def    .
6 six      abc    jkl
7 seven    xxx    mno
8 eight    def    pqr
9 nine     abc    .
10 ten     xxx    stu
run;

proc sql;

  select
    ifc (uq_foo eq cnt, 'foo is unique', 'foo is not unique'),
    ifc (uq_bar eq cnt, 'bar is unique', 'bar is not unique'),
    ifc (uq_baz eq cnt, 'baz is unique', 'baz is not unique')
  from (
    select
      count(*)           as cnt,
      count(unique(foo)) as uq_foo,
      count(unique(bar)) as uq_bar,
      count(unique(baz)) as uq_baz
    from
      tq84_data
  );

quit;
Github repository about-SAS, path: /programming/proc/sql/find-unique-values.sas

describe-table.sas

data some_table;
     attrib
       col_one   label = 'foo'
       col_two   label = 'bar' length = $20.
       col_three label = 'baz' length = $10.
     ;
     col_one   =  42;
     col_two   = 'Hello world.';
     col_three = ' ';
run;

proc sql;
  describe table work.some_table;
quit;
/* 
  create table WORK.SOME_TABLE( bufsize=65536 )
     (
      col_one num label='foo',
      col_two char(20) label='bar',
      col_three char(10) label='baz'
     );
*/
Github repository about-SAS, path: /programming/proc/sql/describe-table.sas

create-table.sas

%let ora_user     = rene;
%let ora_password = secret_garden;
%let ora_server   = ora.test.renenyffenegger.ch;

data tq84_stage;

  length spelled $20;

  input
    val
    spelled $
  ;

datalines;
1 one
2 two
3 three
4 four
5 five
42 forty-two
;


proc sql;
  --
  -- Apparently, the following "connect to oracle"
  -- statement is referred to as "pass through".
  --
  connect to oracle as tq84_ora (
    user     = &ora_user
    password = &ora_password
    path     = &ora_server
  );

  create table
    tq84_ora.a_table_name_3
  as
    select * from tq84_stage;
quit;
Github repository about-SAS, path: /programming/proc/sql/connect-to/oracle/create-table.sas

sas7bdat.sas

libname tq84_dir 'c:\path\to\dir\';

data tq84_dat;

  length spelled $20;

  input
    val
    spelled $
  ;

datalines;
1 one
2 two
3 three
4 four
5 five
42 forty-two
;


proc sql;

  /* Creates file c:\path\to\dir\dat.sas7bdat */
  create table tq84_dir.dat 
  /*  (compress = yes) */
  as
    select
      val,
      spelled
    from
      work.tq84_dat;
  
quit;
Github repository about-SAS, path: /programming/proc/sql/create-table/sas7bdat.sas

rename-columns.sas

data tq84_data;

  length num     8
         en   $ 10
         gr   $ 10
         fr   $ 10;

  input  num en gr fr;

datalines;
1 one   eins un
2 two   zwei deux
3 three drei trois
4 four  vier quattre
5 five  fünf cinque
run;

proc sql;

  create table tq84_long_col_names(
    rename=(en=english
            fr=french
            gr=german)
  )
  as
  select *
  from   tq84_data;

quit;
Github repository about-SAS, path: /programming/proc/sql/create-table/rename-columns.sas

monotonic.sas

data tq84_data;

  length num 8;
  length txt $ 10;
  input  num txt;

datalines;
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine
10 ten
run;

proc sql;
  select
    num,
    txt
  from
    tq84_data
  where
/*  Note: monotonic() evaluated before
          order by */
    monotonic() between 4 and 7
  order by
    txt;
quit;
Github repository about-SAS, path: /programming/proc/sql/monotonic.sas

option-obs.sas

/* Use "global" option obs instead of outobs */
options obs=3;

proc sql;
  select * from sashelp.cars;
quit;
Github repository about-SAS, path: /programming/proc/sql/option-obs.sas

outobs.sas

data tq84_data;
   length num $ 20;

   input  num $
          val;

datalines;
one 1
two 2
three 3
four 4
five 5
six 6
seven 7
eight 8
nine 9
ten 10
eleven 11
twelve 12
thirteen 13
fourteen 14
fivteen 15
sixteen 16
seventeen 17
eighteen 18
nineteen 19
twenty 20
;


proc sql
     outobs=10; /* Select first 10 observations/records */
  select
    *
  from
    tq84_data;
quit;
Github repository about-SAS, path: /programming/proc/sql/outobs.sas

histogram.sas

data rand;
  do i = 1 to 10000;
  norm = rand('norm');
  keep norm;

  output;
  end;

run;


ods graphics on;
proc univariate
  data=rand;
  histogram;
run;
ods graphics off
Github repository about-SAS, path: /programming/proc/univariate/histogram.sas

ifc.sas

data _null_;
  tq84_var  = 42;
  tq84_text = ifc(tq84_var > 40, "tq84_var > 40", "tq84 <= 40");

  put tq84_text;
run;

/* ifc returns a character value. ifn returns a numeric value. */
Github repository about-SAS, path: /programming/functions/ifc.sas

lbound.sas

data _null_;

  array ary_a{   *} a1-a10;
  array ary_b{  10} b1-b10;
  array ary_c{5:14} c1-c10;
  
  lbound_a = lbound(ary_a);
  lbound_b = lbound(ary_b);
  lbound_c = lbound(ary_c);

  put lbound_a=; /* lbound_a=1 */
  put lbound_b=; /* lbound_b=1 */
  put lbound_c=; /* lbound_c=5 */

run;
Github repository about-SAS, path: /programming/functions/lbound.sas

floor.sas

data tq84_data;
  drop i;
  do i = 1 to 20;
     r = rand('norm') * 100 + 1000;
     f = floor(r);
     
     output;
  end;
run;


proc sql;
  select
    *
  from
    tq84_data;
quit;
Github repository about-SAS, path: /programming/functions/floor.sas

mean.sas

data _null_;
  tq84_foo = 10;
  tq84_bar = 14;
  tq84_baz = 18;

  tq84_avg = mean(tq84_foo, tq84_bar, tq84_baz);

  put tq84_avg=;
run;
Github repository about-SAS, path: /programming/functions/mean.sas

hbound.sas

data _null_;

  array ary_a{   *} a1-a10;
  array ary_b{  10} b1-b10;
  array ary_c{5:14} c1-c10;
  
  hbound_a = hbound(ary_a);
  hbound_b = hbound(ary_b);
  hbound_c = hbound(ary_c);

  put hbound_a=; /* hbound_a=10 */
  put hbound_b=; /* hbound_b=10 */
  put hbound_c=; /* hbound_c=14 */

run;
Github repository about-SAS, path: /programming/functions/hbound.sas

mdy.sas

data _null_;

  dt = mdy(8,28,1970);

  put "year:    " dt year.   ;
  put "month:   " dt month.  ;
  put "day:     " dt day.    ;
  
run;
Github repository about-SAS, path: /programming/functions/mdy.sas

upcase.sas

data _null_;

  var    = 'Foo, bar, baz';
  var_up =  upcase(var);    /* Translate var to uppercase */

  put var=   ;
  put var_up=;

run;
Github repository about-SAS, path: /programming/functions/upcase.sas

soundex.sas

proc sql;
  select
    a.name          as name_a,
    b.name          as name_b,
    soundex(a.name) as name_soundex
  from
    sashelp.class a join
    sashelp.class b on soundex(a.name) = soundex(b.name)
  where
    a.name gt b.name;
quit;
Github repository about-SAS, path: /programming/functions/soundex.sas

today.sas

data _null_;
  dt_today = today();
  put dt_today;
run;
Github repository about-SAS, path: /programming/functions/today.sas

dim.sas

data _null_;

  array ary_a{   *} a1-a10;
  array ary_b{  10} b1-b10;
  array ary_c{5:14} c1-c10;

  /* Determine the number of elements in an array */
  dim_a = dim(ary_a);
  dim_b = dim(ary_b);
  dim_c = dim(ary_c);

  put dim_a=; /* dim_a=10 */
  put dim_b=; /* dim_b=10 */
  put dim_c=; /* dim_c=10 */

run;
Github repository about-SAS, path: /programming/functions/dim.sas

extract-parts.sas

data _null_;

  dt = '28aug1970'd;

  put "year:    " dt year.   ;
  put "month:   " dt month.  ;
  put "day:     " dt day.    ;

  put "quarter: " dt qtr.    ;
  put "weekday: " dt weekday.; /* 1 = sunday */

  dt_year    = year   (dt);
  dt_month   = month  (dt);
  dt_day     = day    (dt);
  dt_qtr     = qtr    (dt);
  dt_weekday = weekday(dt);

  /* Note: +(-1) used in order to suppress whitespaces between string literals and variables: */
  put dt_day +(-1) "." dt_month +(-1) "." dt_year +(-1) " (Quarter: " dt_qtr +(-1) ", weeday: " dt_weekday +(-1) ")";
  
run;
Github repository about-SAS, path: /programming/date-and-time/extract-parts.sas

keep-variables.sas

data xy;

/* Keep x and y, don't output i and r */
   keep x y;

   do i = 1 to 100;
      r = rand('norm'); 

      x = r ** 2;
      y = x ** 2;
      
      output;
   end;

run;

proc print
     data = xy;
run;
Github repository about-SAS, path: /programming/data-sets/keep-variables.sas

create-test-data.sas

data tq84_data;
  bar  = 100;
  do i = 1 to 5;

     foo = i * 3;
     bar = bar - foo;
     baz = mean(foo, bar);

     output;
  end;
run;

proc print;
run;
Github repository about-SAS, path: /programming/data-sets/create-test-data.sas

find-unique-values-in-variables.sas

data tq84_data;

  length num    8
         en  $ 10
         fr  $ 10
         gr  $ 10;

  input  num en fr gr;

datalines;
1 one    un     eins
2 two    deux   zwei
3 three  trois  drei
4 four   .      vier
5 five   cinque fünf
6 six    .      .
7 seven  .      sieben
8 eight  huit   .
9 nine   neuf   neun
10 ten   dix    zehn
run;


%let lib=WORK;
%let tab=TQ84_DATA;

proc sql noprint;
   select
     catx(' ', "count(*) - count(distinct ", name,") as ", name)
   into
     :cols separated by ','
   from
     sashelp.vcolumn
   where
     libname="&lib" and
     memname="&tab";
quit;

%put &cols;


proc sql noprint;
  create table
    cnt_dist_&tab
  as
  select
    &cols
  from
    &lib..&tab;
quit;


proc sql;
  select * from cnt_dist_&tab;
quit;


proc transpose
     data=cnt_dist_&tab
     out=unique_&tab;
run;


proc sql;
  select
    catt(_name_, ' is ', ifc(col1 eq 0, '', ' not'), ' unique')
  from
    unique_&tab;
quit;
Github repository about-SAS, path: /programming/data-sets/find-unique-values-in-variables.sas

Password protected data sets

Data sets can be password protected on three levels: reading, writing and modfication (alter):
data pw_protected (
        write=pw_w
        read =pw_r
        alter=pw_a
     );

  x='eggs';
  y='why' ;
  z= 42   ;

  output;

run;


data cp_pw_protected;
  set pw_protected(pw=pw_r);
run;

proc sql;
  select * from pw_protected(pw=pw_r);
run;

proc sql;
  select * from cp_pw_protected;
run;

proc sql;
  update pw_protected(pw=pw_w)
  set z = z*2;
quit;
Github repository about-SAS, path: /programming/data-sets/password-protected.sas

include.sas

%include "s:\path\to\included-file.sas";
Github repository about-SAS, path: /macro-processor/include.sas

datatyp.sas

/* %datatyp returns either NUMERIC or CHAR */

data _null_;

  %let fourty_two = 42;
  %let foo        ="bar";

  put "fourty_two is %datatyp(&fourty_two)";
  put "foo is %datatyp(&foo)";

run;
Github repository about-SAS, path: /macro-processor/autocall/datatyp.sas

fibonacci.sas

--
-- Recursively calling a macro.
--
%macro fibonacci(n);
  %if       &n eq 0 %then 1;
  %else %if &n eq 1 %then 1;
  %else %eval(%fibonacci(%eval(&n-1)) + %fibonacci(%eval(&n-2)));
%mend;

%macro put_fibonacci_numbers(n);

  %do i=1 %to &n;
      %put fibonacci number &i is %fibonacci(&i);
  %end;

%mend put_fibonacci_numbers;


%put_fibonacci_numbers(10);
Github repository about-SAS, path: /macro-processor/fibonacci.sas

indirect-macro-expansion.sas

%macro foo;
  this is from macro foo
%mend foo;

%macro bar;
  this is from macro bar
%mend bar;

%macro put_named_macro(macro_name);
  %put macro &macro_name expands to >%&macro_name<;
%mend put_named_macro;

%put_named_macro(foo);
Github repository about-SAS, path: /macro-processor/indirect-macro-expansion.sas

scan.sas

* find nth word;
%put "Third word is: " %scan(one two three four five six, 3);
Github repository about-SAS, path: /macro-processor/functions/scan.sas

index.sas

* find position of character;
%put "position of first w is " %index(Hello world, w);
Github repository about-SAS, path: /macro-processor/functions/index.sas

substr.sas

%put %substr(foo bar baz, 5, 3);
Github repository about-SAS, path: /macro-processor/functions/substr.sas

sysprod.sas

%macro is_licensed(prod);
  %if %sysprod(&prod) = 1 %then %put &prod is licensed;
                          %else %put &prod is not licensed;
%mend is_licensed;

%is_licensed(af         );
%is_licensed(assist     );
%is_licensed(base       );
%is_licensed(calc       );
%is_licensed(connect    );
%is_licensed(cpe        );
%is_licensed(eis        );
%is_licensed(ets        );
%is_licensed(fsp        );
%is_licensed(gis        );
%is_licensed(graph      );
%is_licensed(ph-clinical);
%is_licensed(qc         );
%is_licensed(share      );
%is_licensed(stat       );
%is_licensed(toolkit    );
Github repository about-SAS, path: /macro-processor/functions/sysprod.sas

length.sas

%put %length("foo bar baz");
Github repository about-SAS, path: /macro-processor/functions/length.sas

See also

SAS Programming Language
SAS statements

Index