├── .gitignore ├── Clinical ├── ADaM │ ├── adeg.sas │ ├── bocf.sas │ ├── locf.sas │ └── locf2.sas ├── SDTM │ ├── se.sas │ ├── ta.sas │ └── te.sas ├── dataMgt │ ├── Array_transpose.sas │ └── baselineChanges.sas ├── file_exchange │ ├── Xport.sas │ └── import_xml.sas └── stats │ ├── chisq.sas │ ├── ttest.sas │ └── univariate.sas ├── INFormats.sas ├── New9.sas ├── Num_func.sas ├── PrintPro.sas ├── README.md ├── Xter_func.sas ├── array2.sas ├── arrays.sas ├── debug.sas ├── dictionary.sas ├── doloop.sas ├── formats.sas ├── gplots.sas ├── graphs.sas ├── im_export.sas ├── listing.sas ├── listing2.sas ├── listing3.sas ├── listing4.sas ├── macro2.sas ├── macros.sas ├── procTab.sas ├── proc_datasets.sas ├── put.sas ├── putlog.sas ├── report.sas ├── revision.sas ├── select.sas ├── sortLin.sas ├── sql.sas ├── sql2.sas ├── sql3.sas ├── trailingAT.sas └── transpose.sas /.gitignore: -------------------------------------------------------------------------------- 1 | git 2 | CVS 3 | .svn 4 | .hg 5 | .lock-wscript 6 | .wafpickle-N 7 | .*.swp 8 | .DS_Store 9 | ._* 10 | npm-debug.log 11 | .npmrc 12 | node_modules 13 | config.gypi 14 | *.orig 15 | __* 16 | _* 17 | .vscode 18 | 19 | 20 | -------------------------------------------------------------------------------- /Clinical/ADaM/adeg.sas: -------------------------------------------------------------------------------- 1 | options validvarname=upcase; 2 | 3 | libname sdtm "/folders/myshortcuts/Sas_Training/SDTAM"; 4 | %let ggg=/folders/myshortcuts/Sas_Training/ADaM/EG.sas; 5 | %include "&ggg"; 6 | 7 | 8 | 9 | %let keepvar2=studyid usubjid egeval egcat aval avalc ablfl param paramcd 10 | adt atm avisitn avisit base norm EGSTRESN; 11 | 12 | 13 | data adeg_1; 14 | attrib studyid label='Study Identifier' 15 | usubjid label='Unique Study Identifier' 16 | egeval label='Evaluator' 17 | egcat label='Category for ECG' 18 | aval label='Numeric Result in Standard Format' 19 | avalc label='Character Result in Standard Format' 20 | ablfl label='Baseline Flag' 21 | param label='Parameter Description' 22 | paramcd label='Parameter Code' 23 | adt label='Actual Date of ECG Taken' Format=date9. 24 | atm label='Actual Time of ECG Taken' Format=time5. 25 | avisitn label='Analysis Visit number' 26 | avisit label='Analysis Visit ' 27 | base label='Baseline Value' 28 | chg label='Change from Baseline Value' 29 | pchg label='Percentage Change from Baseline Value' 30 | norm label='Abnormality' 31 | ; 32 | set work.eg; 33 | aval=EGSTRESN; 34 | avalc=EGSTRESC; 35 | ablfl=EGBLFL; 36 | param=EGTEST; 37 | paramcd=EGTESTCD; 38 | adt=EGDTC; 39 | atm=EGDTC; 40 | avisitn=VISITNUM/10; 41 | avisit=VISIT ; 42 | if EGBLFL="Y" then base=EGSTRESN; 43 | if EGTESTCD='INTP' then norm=EGSTRESC; 44 | keep &keepvar2; 45 | run; 46 | 47 | 48 | proc sort data=adeg_1 out=adeg_2; 49 | by usubjid param avisitn; 50 | run; 51 | 52 | 53 | data adeg; 54 | set adeg_2; 55 | retain dummy; 56 | by usubjid param avisitn; 57 | if first.usubjid then dummy=base; 58 | if not first.usubjid and EGSTRESN ne . then do; 59 | if base ne . then dummy=base; 60 | else base=dummy; 61 | chg=EGSTRESN-BASE; 62 | pchg=100*(EGSTRESN-BASE)/BASE; 63 | end; 64 | drop=EGSTRESN; 65 | run; 66 | 67 | 68 | proc print data=adeg; 69 | run; -------------------------------------------------------------------------------- /Clinical/ADaM/bocf.sas: -------------------------------------------------------------------------------- 1 | * Baseline observation carried forward(BOCF); 2 | * create $visit format; 3 | proc format; 4 | value $visit "1"="Screening" 5 | "2"="Baseline" 6 | "3"-"6"="Routine" 7 | "7"="Closeout" 8 | "8"="Follow-up" 9 | ; 10 | run; 11 | 12 | 13 | 14 | * create dataset; 15 | data height; 16 | do subjid=1 to 100; 17 | do visit=1 to 8; 18 | height=ceil(220 * ranuni(2345)); 19 | if height < 160 then height = .; 20 | visitc=put(visit,1.); 21 | output; 22 | end; 23 | end; 24 | format visitc $visit.; 25 | run; 26 | 27 | proc sort data=height out=sortH; 28 | by subjid visit; 29 | run; 30 | 31 | 32 | * Generate baseline; 33 | data baseheight; 34 | set sortH(where=(visit not eq 1)); 35 | retain baseline; 36 | by subjid; 37 | if visit eq 2 then baseline=height; 38 | 39 | * if height for visit 2 is missing then locf to become baseline ; 40 | else if baseline = . and height ne . then baseline=height; 41 | 42 | if height = . then height = baseline; 43 | run; 44 | 45 | 46 | 47 | * Generate baseline flag; 48 | 49 | data baseFlag; 50 | set heama; 51 | by subjid visit; 52 | retain basefl; 53 | if first.subjid then basefl = " "; 54 | if visit = 2 then basefl = "Y"; 55 | label basefl = "Visit Baseline Flag" 56 | run; 57 | 58 | 59 | data bflag2; 60 | do until (last.subjid); 61 | set heama; 62 | by subjid visit; 63 | if visit = 2 then basefl = "Y"; 64 | else basefl = " "; 65 | output; 66 | end; 67 | label basefl = "Visit Baseline Flag" 68 | run; -------------------------------------------------------------------------------- /Clinical/ADaM/locf.sas: -------------------------------------------------------------------------------- 1 | * Last observation carried forward(LOCF); 2 | * create $visit format; 3 | proc format; 4 | value $visit "1"="Screening" 5 | "2"="Baseline" 6 | "3"-"6"="Routine" 7 | "7"="Closeout" 8 | "8"="Follow-up" 9 | ; 10 | run; 11 | 12 | 13 | 14 | * create dataset; 15 | data height; 16 | do subjid=1 to 100; 17 | do visit=1 to 8; 18 | height=ceil(220 * ranuni(2345)); 19 | if height < 160 then height = .; 20 | visitc=put(visit,1.); 21 | output; 22 | end; 23 | end; 24 | format visitc $visit.; 25 | run; 26 | 27 | 28 | * Do traditional locf; 29 | data locf; 30 | set height; 31 | by subjid; 32 | retain locf; 33 | if first.subjid then locf=.; 34 | if height ne . then locf=height; 35 | else height=locf; 36 | run; 37 | 38 | 39 | * Do DOW locf; 40 | data locf2; 41 | do until(last.subjid); 42 | set height; 43 | by subjid; 44 | if height ne . then locf=height; 45 | output; 46 | end; 47 | run; 48 | 49 | 50 | * Generate baseline; 51 | data baseheight; 52 | do until(last.subjid); 53 | set locf2; 54 | by subjid; 55 | if visit eq 1 then baseline = .; 56 | if visit eq 2 then baseline=height; 57 | else if baseline = . and height ne . then baseline=height; 58 | output; 59 | end; 60 | run; 61 | 62 | * Sort data by subjid and visit; 63 | proc sort data=height out=heama; 64 | by subjid visit; 65 | run; 66 | 67 | * Generate baseline flag; 68 | 69 | data baseFlag; 70 | set heama; 71 | by subjid visit; 72 | retain basefl; 73 | if first.subjid then basefl = " "; 74 | if visit = 2 then basefl = "Y"; 75 | label basefl = "Visit Baseline Flag" 76 | run; 77 | 78 | 79 | data bflag2; 80 | do until (last.subjid); 81 | set heama; 82 | by subjid visit; 83 | if visit = 2 then basefl = "Y"; 84 | else basefl = " "; 85 | output; 86 | end; 87 | label basefl = "Visit Baseline Flag" 88 | run; -------------------------------------------------------------------------------- /Clinical/ADaM/locf2.sas: -------------------------------------------------------------------------------- 1 | option validvarname=upcase; 2 | 3 | option validvarname=upcase; 4 | 5 | data vv(drop=num); 6 | length visit $10. subjid $3.; 7 | do subjid="101" ,"102"; 8 | visnum = 0; 9 | visit="Screening"; 10 | output; 11 | do num=2 to 14 by 2; 12 | visnum=num; 13 | visit="Week "||put(num,2.); 14 | output; 15 | end; 16 | end; 17 | run; 18 | 19 | 20 | 21 | data vv2; 22 | input subjid $3. visit $10. value stdy; 23 | if visit="Screening" then visnum=0; 24 | else visnum=input(substr(visit,6),2.); 25 | cards; 26 | 101 Screening 11.13 -1 27 | 101 Week 4 12.33 28 28 | 101 Week 6 23.25 42 29 | 101 Week 14 14.25 96 30 | 101 Week 18 31.18 126 31 | 102 Week 2 21.28 14 32 | 102 Week 8 23.34 56 33 | 102 Week 14 25.21 96 34 | ; 35 | run; 36 | 37 | 38 | proc sort data=vv2; by subjid visnum ; run; 39 | proc sort data=vv; by subjid visnum; run; 40 | 41 | 42 | * Do traditional locf; 43 | data final2(drop= v1 v2); 44 | retain v1 v2; 45 | merge vv2 vv; 46 | by subjid visnum; 47 | if first.subjid then v1=.; 48 | if visnum < 20 then do; 49 | if value =. then value=v1; 50 | else v1=value; 51 | end; 52 | else if 20 <= visnum < 160 then do; 53 | if value =. then value=v2; 54 | else v2=value; 55 | end; 56 | run; 57 | 58 | * tradional locf II ; 59 | data locf2(drop=dummy); 60 | set vv2; 61 | retain dummy; 62 | by subjid visnum; 63 | if not first.subjid then do; 64 | if value ne . then dummy=value; 65 | else value=dummy; 66 | end; 67 | else dummy=value; 68 | run; 69 | 70 | 71 | * Do DOW locf; 72 | data final3(drop=locf); 73 | do until(last.subjid); 74 | merge vv2 vv; 75 | by subjid visnum; 76 | if value ne . then locf=value; 77 | else value=locf; 78 | output; 79 | end; 80 | run; 81 | 82 | 83 | proc compare base=final2 comp=final3; 84 | run; -------------------------------------------------------------------------------- /Clinical/SDTM/se.sas: -------------------------------------------------------------------------------- 1 | option validvarname=upcase; 2 | 3 | * Add se domain; 4 | %let varkeep=studyid domain usubjid etcd element taetord epoch sestdtc seendtc; 5 | data se; 6 | attrib studyid label='Study Identifier' length=$6 7 | domain label='Domain Abbreviation' length=$2 8 | usubjid label='Unique Subject Identifier' length=$22 9 | * seseq label='Sequence Number' length=8; 10 | etcd label='Element Code' length=$6 11 | element label='Description of Element' length=$9 12 | seupdes label='Description of Unplanned Element' length=$40 13 | sestdtc label='Start Date/Time of Element' length=$10 14 | seendtc label='End Date/Time of Element' length=$10 15 | taetord label='Planned Order of Elements with Arm' length=8 16 | epoch label='Epoch' length=$9 17 | ; 18 | set sasuser.svdtc(keep=pt stud_sit visit vis_d) ; 19 | studyid="SCL002"; 20 | domain="SE"; 21 | usubjid=studyid||'-'||strip(stud_sit)||"-0"||strip(substr(pt, 5, 1)); 22 | /* seseq=; 23 | if visit in (1, 10) then do; 24 | etcd="SCREEN"; element="Screening"; taetord=1; epoch="Screening"; 25 | end; 26 | if visit=20 then do; 27 | etcd="BASE"; element="Baseline"; taetord=2; epoch="Treatment"; 28 | end; 29 | if visit=30 then do; 30 | etcd="TREAT"; element="Treatment"; taetord=3; epoch="Treatment"; 31 | end; 32 | if visit=40 then do; 33 | etcd="FU"; element="Follow-up"; taetord=4; epoch="Follow-up"; 34 | end; */ 35 | 36 | if visit in (1, 10) then do; 37 | etcd="SCRN"; element="Screen"; taetord=1; epoch="Screening"; 38 | end; 39 | if visit=20 then do; 40 | etcd="K"; element="SCLA"; taetord=2; epoch="Treatment"; 41 | end; 42 | if visit=40 then do; 43 | etcd="FU"; element="Follow-up"; taetord=3; epoch="Follow-up"; 44 | end; 45 | 46 | sestdtc=put(vis_d, yymmdd10.); 47 | seendtc=put(vis_d, yymmdd10.); 48 | keep &varkeep; 49 | run; 50 | 51 | 52 | * Generating sequence number; 53 | * first sort the data; 54 | proc sort data=se; 55 | by usubjid sestdtc etcd; 56 | run; 57 | 58 | data se; 59 | set se; 60 | attrib seseq label='Sequence Number' length=8; 61 | by usubjid sestdtc etcd; 62 | if first.usubjid then seseq=1; 63 | else seseq+1; 64 | where etcd is not missing; 65 | run; -------------------------------------------------------------------------------- /Clinical/SDTM/ta.sas: -------------------------------------------------------------------------------- 1 | option validvarname=upcase; 2 | 3 | 4 | 5 | * Add ta domain; 6 | data ta; 7 | attrib studyid label='Study Identifier' length=$10 8 | domain label='Domain Abbreviation' length=$2 9 | armcd label='Planned Arm Code' length=$8 10 | arm label='Description of Planned Arm' length=$200 11 | taetord label='Order of Element within Arm' length=8 12 | etcd label='Element Code' length=$8 13 | element label='Description of Element' length=$200 14 | tabranch label='Branch' length=$200 15 | tatrans label='Transition Rule' length=$200 16 | epoch label='Epoch' length=$200 17 | ; 18 | studyid="SCL002"; 19 | domain="TA"; 20 | tabranch=""; 21 | tatrans=""; 22 | armcd="A"; 23 | arm="Adult"; 24 | etcd="SCRN"; element="Screen"; taetord=1; epoch="Screen"; output; 25 | etcd="K"; element="SCLA"; taetord=2; epoch="Treatment"; output; 26 | etcd="FU"; element="Follow-Up"; taetord=3; epoch="Follow-Up"; output; 27 | 28 | armcd="C"; arm="Child"; 29 | etcd="SCRN"; element="Screen"; taetord=1; epoch="Screen"; output; 30 | etcd="K"; element="SCLA"; taetord=2; epoch="Treatment"; output; 31 | etcd="FU"; element="Follow-Up"; taetord=3; epoch="Follow-Up"; output; 32 | run; 33 | 34 | 35 | -------------------------------------------------------------------------------- /Clinical/SDTM/te.sas: -------------------------------------------------------------------------------- 1 | * Generating the TE domain(dataset); 2 | options validvarname=upcase; 3 | 4 | data te; 5 | attrib studyid label='Study Identifier' length=$10 6 | domain label='Domain Abbreviation' length=$2 7 | ectd label='Element Code' length=$8 8 | element label='Description of Element' length=$200 9 | testrl label='Rule for Start of Element' length=$200 10 | teenrl label='Rule for End of Element' length=$200 11 | tedur label='Planned Duration of Element' length=$20 12 | ; 13 | studyid = "SCL002"; 14 | domain = "TE"; 15 | ectd = "SCRN"; 16 | element = "Screen"; 17 | testrl = "Informed Consent"; 18 | teenrl = "Screening Assessments are complete, up to 1 week after start of Element"; 19 | tedur = "P7D"; output; 20 | 21 | ectd = "K"; 22 | element = "SCLA"; 23 | testrl = "First dose of study drug"; 24 | teenrl = "4 days to 1 week after start of element"; output; 25 | 26 | ectd = "FU"; 27 | element = "Follow Up"; 28 | testrl = "After the last PK plasma sample or 1 week after last dose"; 29 | teenrl = "Ends 1 weeks after start of element"; output; 30 | run; 31 | 32 | -------------------------------------------------------------------------------- /Clinical/dataMgt/Array_transpose.sas: -------------------------------------------------------------------------------- 1 | option validvarname=upcase; 2 | 3 | * This will transpose(Normalise) our data; 4 | 5 | data vsflat; 6 | set vssort; 7 | by usubjid; 8 | keep usubjid visit1-visit7; 9 | retain visit1-visit7; 10 | array visit{7}; 11 | if first.usubjid then call missing(of visit[*]); 12 | visit{visitnum}=vsstresn; 13 | if last.usubjid; 14 | run; 15 | 16 | 17 | proc print data=vsflat; 18 | run; -------------------------------------------------------------------------------- /Clinical/dataMgt/baselineChanges.sas: -------------------------------------------------------------------------------- 1 | option validvarname=upcase; 2 | 3 | * This calculate change from baseline and percentage change from baseline; 4 | data VS; 5 | label USUBJID = "Unique Subject Indentifier" 6 | VSTESTCD = "Vitals Signs Test Short Name" 7 | VISITNUM = "Visit Number" 8 | VSSTRESN = "Numeric Result/Finding in Standard Units"; 9 | input USUBJID $ VSTESTCD $ VISITNUM VSSTRESN @@; 10 | datalines; 11 | 101 SBP 0 160 101 DBP 0 60 12 | 101 SBP 1 140 101 DBP 1 80 13 | 101 SBP 2 150 101 DBP 2 90 14 | 101 SBP 3 180 101 DBP 3 100 15 | 101 SBP 4 180 101 DBP 4 66 16 | 101 SBP 5 180 101 DBP 4 99 17 | 102 SBP 0 160 102 DBP 0 70 18 | 102 SBP 1 170 102 DBP 1 80 19 | 102 SBP 2 190 102 DBP 2 90 20 | 102 SBP 3 110 102 DBP 3 79 21 | 102 SBP 4 150 102 DBP 4 72 22 | 102 SBP 5 150 102 DBP 5 98 23 | 103 SBP 0 161 103 DBP 0 69 24 | 103 SBP 1 169 103 DBP 1 95 25 | 103 SBP 2 188 103 DBP 2 99 26 | 103 SBP 3 148 103 DBP 3 78 27 | 103 SBP 4 159 103 DBP 4 97 28 | 103 SBP 5 159 103 DBP 5 101 29 | ; 30 | run; 31 | 32 | proc sort data=vs out=vssorted; 33 | by USUBJID VSTESTCD VISITNUM; 34 | run; 35 | 36 | 37 | data advs; 38 | set vssorted; 39 | by USUBJID VSTESTCD VISITNUM; 40 | 41 | Label AVAL = "Analysis Value" 42 | PARAMCD = "Parameter Code" 43 | AVISITN = "Analysis Visit(N)" 44 | ABLFL = "Baseline Record Flag" 45 | BASELINE = "Baseline Value" 46 | CHG = "Change from Baseline" 47 | PCHG = "Percentage Change from Baseline"; 48 | 49 | aval = vsstresn; 50 | paramcd = vstestcd; 51 | avisitn = visitnum; 52 | 53 | retain baseline; 54 | 55 | if first.vstestcd then 56 | do; 57 | ablfl="Y"; 58 | baseline = aval; 59 | end; 60 | else do; 61 | change = aval - baseline; 62 | pchg = ((aval - baseline) / baseline) * 100; 63 | end; 64 | run; 65 | 66 | 67 | proc print data=advs; 68 | var usubjid aval baseline change pchg; 69 | run; -------------------------------------------------------------------------------- /Clinical/file_exchange/Xport.sas: -------------------------------------------------------------------------------- 1 | * Import CDISC SAS transport file; 2 | libname sastrans XPORT "C:\adeg.xpt"; 3 | libname muser "C:\sastraining\sasTransport"; 4 | 5 | 6 | * Using Sql procedure ; 7 | proc copy in=sastrans out=muser memtype=data; 8 | select egk; 9 | run; 10 | 11 | 12 | * Using dataset step ; 13 | data sastrans.ekg; 14 | select muser.ekg; 15 | end; -------------------------------------------------------------------------------- /Clinical/file_exchange/import_xml.sas: -------------------------------------------------------------------------------- 1 | * Using XML libname engine to read xml data; 2 | 3 | libname xml2 xmlv2 xmlmap=xml_map; 4 | filename xml_map "C:\xml_map.map"; 5 | filename myxml "c:\file33.xml"; 6 | 7 | 8 | proc contents 9 | data=xml2.myxml; 10 | run; 11 | 12 | proc print 13 | data=xml2.myxml; 14 | run; -------------------------------------------------------------------------------- /Clinical/stats/chisq.sas: -------------------------------------------------------------------------------- 1 | * Chi-square test; 2 | * Chi-square test is useful for detection of general association not particular relationship 3 | * between treatment and categorical response i.e ordinal and nominal in clinical trial; 4 | * this is usually using proc freq with chisq option; 5 | data chiTest; 6 | input trt $ adae $ adct; 7 | datalines; 8 | Active Y 50 9 | Active N 28 10 | Placebo Y 30 11 | Placebo N 78 12 | ; 13 | run; 14 | 15 | * conduct chi-square test; 16 | proc freq data=chiTest; 17 | table trt*adea / chisq; 18 | weight adct; 19 | output out=chstats chisq; 20 | run; 21 | 22 | 23 | 24 | proc logistic data=adsl; 25 | model aval(event="1") = baseline sexn racen trtpn / clodds = wald; 26 | run; -------------------------------------------------------------------------------- /Clinical/stats/ttest.sas: -------------------------------------------------------------------------------- 1 | proc ttest data=sashelp.class; 2 | class sex; 3 | var height; 4 | run; 5 | -------------------------------------------------------------------------------- /Clinical/stats/univariate.sas: -------------------------------------------------------------------------------- 1 | * Generate dataset; 2 | data adsl; 3 | infile datalines dsd missover dlm=" "; 4 | input usubjid $3. sex $1. height weight @@; 5 | datalines; 6 | 101 F 122 234 111 M 162 234 121 F 153 240 122 M 144 242 7 | 102 F 109 238 122 F 122 236 123 M 173 235 126 M 152 270 8 | 103 M 113 250 113 M 162 251 133 M 143 252 127 F 182 251 9 | 104 M 191 248 105 F 141 180 125 F 132 190 128 M 149 259 10 | 106 F 123 235 110 M 165 238 112 F 158 249 114 M 154 232 11 | 107 F 110 248 115 F 126 232 116 M 183 245 117 M 142 278 12 | 108 M 123 255 118 M 169 259 119 M 153 242 120 F 189 255 13 | 109 M 192 249 124 F 161 188 129 F 142 199 130 M 169 269 14 | ; 15 | run; 16 | 17 | 18 | * Generate all tables for selected numeric variables; 19 | proc univariate data=adsl; 20 | var height weight; 21 | run; 22 | 23 | 24 | * using ods select to select specific output; 25 | title 'Height and Weight descriptive statistics'; 26 | ods select BasicMeasures Quantiles; 27 | proc univariate data=adsl; 28 | var height weight; 29 | run; 30 | 31 | * using by statement to get descriptive statistics for subunit/group; 32 | * first sort the data; 33 | proc sort data=adsl out=adsl2; 34 | by sex; 35 | run; 36 | 37 | 38 | title "Height and Weight descriptive statistics by sex"; 39 | ods select BasicMeasures; 40 | proc univariate data=adsl2; 41 | by sex; 42 | var height weight; 43 | run; 44 | -------------------------------------------------------------------------------- /INFormats.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical"; 2 | Filename timeq2 "C:\Users\Jose\Documents\SasClinical\chapter1"; 3 | 4 | /* Create formats to write currencies for India, Nigeria and Zimbabwe*/ 5 | proc format library=home; 6 | picture fmtindr low-high ='000,000,000.00' 7 | (prefix='Rs. ' mult=100); 8 | 9 | picture fmtngn low-high ='000,000,000.00' 10 | (prefix='=N=' mult=100); 11 | 12 | picture fmtzabw 13 | low-high ='000,000,000.00' 14 | (prefix='ZBW' mult=100); 15 | 16 | run; 17 | 18 | * To print the format name and attributes ; 19 | proc format library=home fmtlib; 20 | run; 21 | 22 | options fmtsearch=(home); * reference to the library where the format is stored 23 | * Run the option before using the informat; 24 | 25 | 26 | data home.DateNew; 27 | infile timeq2(ex1.txt) dlm='09'X; 28 | input FlightNo$ Dest$ TravelDate RevFClass RevEClass TotalRevF :$13. TotalRevE :$13. TravelTime; 29 | informat TravelDate mmddyy10. TravelTime time8. ; 30 | Format TravelDate date9. TravelTime time8.; 31 | Run; 32 | 33 | 34 | proc print data=home.DateNew; 35 | run; 36 | 37 | /* This section will use National Language Support (NLS) 38 | for Britian, India and United Arab Emirate */ 39 | data home.Currency; 40 | infile datalines; 41 | input Amount1-Amount3; 42 | format Amount1 nlmnigbp16.2 Amount2 nlmnlinr14.2 Amount3 NLMNIAED16.2; 43 | datalines; 44 | 18384 494394 493493 45 | 32432 983438 5918573 46 | 58384 4458454 525454 47 | 4728454 48545 5488545 48 | 52954 745052 8494845 49 | 2040540 25440 954902 50 | ; 51 | run; 52 | 53 | proc print data=home.Currency; 54 | run; 55 | 56 | 57 | /* Write out the file using dsd - double quotes and comma delimiter*/ 58 | data _null_; 59 | set home.Currency; 60 | file timeq2(Revenue.txt) dsd; 61 | put Amount1-Amount3; 62 | format Amount1 nlmnigbp16.2 Amount2 nlmnlinr14.2 Amount3 NLMNIAED16.2; 63 | run; 64 | 65 | 66 | 67 | * Write out the file using dlm= " "; 68 | data _null_; 69 | set home.Currency; 70 | file timeq2(Revenue2.txt) dlm=" "; 71 | put Amount1 :nlmnigbp14. Amount2 :nlmnlinr14. Amount3 :NLMNIAED18.; 72 | run; 73 | 74 | 75 | data home.Currency2; 76 | infile timeq2(Revenue2.txt); 77 | input Month1 :nlmnigbp14. Month2 :nlmnlinr14. Month3 :NLMNIAED18.; 78 | run; 79 | 80 | proc print data=home.Currency2; 81 | format Month1 :nlmnigbp14. Month2 :nlmnlinr14. Month3 :NLMNIAED18.; 82 | run; 83 | 84 | /* Apply user defined formats */ 85 | proc print data=home.Currency2; 86 | format Month1 :fmtzabw14. Month2 :fmtindr16. Month3 :fmtngn14.; 87 | run; -------------------------------------------------------------------------------- /New9.sas: -------------------------------------------------------------------------------- 1 | * Write message to log using putlog; 2 | data putlog1; 3 | set sashelp.class; 4 | putlog _all_; 5 | putlog name sex weight height; 6 | putlog name " height is " height "inches"; 7 | putlog "NOTE: THIS WRITE NOTE message IN BLUE"; 8 | putlog "WARNING: THIS WRITE WARNINGS message IN GREEN"; 9 | putlog "ERROR: THIS WRITE ERROR message IN RED"; 10 | run; 11 | 12 | data _null_; 13 | set sashelp.class; 14 | array my_arr{*} _numeric_; 15 | array numer{*} _character_; 16 | put my_arr(*) numer(*); 17 | put name age sex weight height; 18 | putlog name age sex weight height; 19 | put _ALL_; 20 | putlog _all_; 21 | run; 22 | 23 | 24 | * The integer in operators; 25 | data badair; 26 | set sashelp.air; 27 | if air in(0:186); 28 | run; 29 | 30 | 31 | * using ifn and ifc; 32 | data putinfile2; 33 | infile datalines missover; 34 | input name $ age sex $; 35 | age = ifn(age le 0, 50, age); 36 | sex = ifc(sex = " ", "Unknown", sex); 37 | datalines; 38 | Mark . M 39 | Uju 35 F 40 | Kelly . 41 | Keth 24 F 42 | ; 43 | run; -------------------------------------------------------------------------------- /Num_func.sas: -------------------------------------------------------------------------------- 1 | * using lag and diff function; 2 | * lag function returns the value of previous variable; 3 | * diff function returns the diff between current and previous value of variable; 4 | libname home2 "C:\Users\Jose\Documents\SasClinical\chapter2"; 5 | 6 | proc format; 7 | value monthfmt 1="January" 2="February" 3="March" 4="April" 8 | 5="May" 6="June" 7="July" 8="August" 9 | 9="September" 10="October" 11="November" 12="December" 10 | ; 11 | run; 12 | 13 | data home.testLG; 14 | infile datalines; 15 | input ID $ week Wt @@; 16 | datalines; 17 | 101 1 234 101 2 236 101 3 240 101 4 242 18 | 102 1 238 102 2 236 102 3 235 102 4 248 102 5 250 19 | 103 1 250 103 2 251 103 3 252 20 | 104 1 248 104 2 250 104 5 234 104 4 236 104 3 267 21 | 105 1 180 105 2 190 105 3 236 105 5 240 101 4 242 22 | ; 23 | run; 24 | 25 | 26 | proc sort data=home.testsort out=home.testsort; 27 | by ID week; 28 | run; 29 | 30 | 31 | * lag will lag the values by 1 i.e shift the value to prior value; 32 | * dif function will calculate the difference between value and value before it; 33 | data home.lagdiff; 34 | set home.testsort; 35 | by ID week; 36 | lagg = lag(wt); 37 | diff = dif(wt); 38 | P_change = diff / lagg * 100; 39 | if first.ID then P_change = 0; 40 | run; 41 | 42 | 43 | 44 | * Ceil function returns smallest integer greater then the input argument; 45 | * Floor function returns the largest integer than is less than or smaller then the input argument; 46 | * Round function return the value of the first argument the nearest multiples of the; 47 | * second argument or whole integer if second argument is missing; 48 | data _null_; 49 | floorme = 123.98; 50 | ceilme = 289.33; 51 | roundme = 345.45; 52 | floorm = floor(floorme); 53 | ceilm = ceil(ceilme); 54 | roundm = round(roundme); 55 | roundm2 = round(roundme,10) 56 | put floorme= ceilme= roundme=; 57 | put floorm= ceilm= roundm=; 58 | run; 59 | 60 | 61 | 62 | 63 | * mdy, intck, intnx functions; 64 | * mdy function returns the month, year, day, weekday, quarter of the date; 65 | * intck returns the time interval between 2 datalines; 66 | * intnx returns a future date give a time interval; 67 | * The date need format to print out well, except it will print as number; 68 | * Remember sas dates are stored as number of days from 1 Jan 1960; 69 | data home.anniversary(drop=yr tmonth) home.serviceyears (drop=yr tmonth); 70 | set sasuser.mechanics(keep=id lastname firstname hired birth); 71 | Yr= intck('year',hired, today()); 72 | retire = intnx('month',birth, 65*12,"end"); 73 | tmonth = month(today()); 74 | MonthEmployed = month(hired); 75 | YearsInService = put(yr,2.)|| " Years in Service"; 76 | Retirement = 'Retirement is on '||put(retire,date9.); 77 | dayto = mdy(01,23,2018); 78 | if Yr gt 20 and month(hired)=tmonth then output anniversary; 79 | output serviceyears; 80 | format YearsInService $35. MonthEmployed monthfmt. dayto date9.; 81 | run; 82 | 83 | 84 | 85 | proc print data=home.anniversary; 86 | title "More than 20-year Anniversaries in month of August"; 87 | run; 88 | title; 89 | 90 | 91 | proc print data=serviceyears; 92 | title "Employee years of service"; 93 | run; 94 | title; 95 | 96 | 97 | 98 | 99 | * Using time and related functions; 100 | data timme; 101 | tm = time(); 102 | date2 = '09jul2018'd; 103 | time1 = hms(05,12,18); 104 | time2 = '14:56:51't; 105 | dtime = datetime(); 106 | dtime2 = dhms(date2,19,32,14); 107 | format tm time1 time2 time8. dtime dtime2 datetime18.; 108 | run; 109 | 110 | 111 | * using yrdiff, timepart, datepart function; 112 | data parttd; 113 | input dt : datetime18.; 114 | format dt datetime18.; 115 | birthd = '09jun1989'd; 116 | todayd = today(); 117 | ageyr = round(yrdiff(todayd, birthd, 'actual')); 118 | datame = '09mar2018:18:38:45'dt; 119 | dpart = datepart(datame); 120 | tpart = timepart(datame); 121 | datalines; 122 | 12jun2008:14:09:59 123 | ; 124 | run; 125 | 126 | 127 | * Missing function; 128 | * Returns 1 is value is missing or 0 is not missing; 129 | data _null_; 130 | set home.health end=eof; 131 | array num{*} _Numeric_; 132 | array Str{*} _Character_; 133 | do i=1 to dim(num); 134 | if missing(num[i]) then countNum+1; 135 | end; 136 | do i=1 to dim(Str); 137 | if missing(Str[i]) then countStr+1; 138 | end; 139 | put countNum= countStr=; 140 | run; 141 | 142 | 143 | * sum function in data step and sum statement in proc print; 144 | * sum in data step, sum the observations, row summation; 145 | data sumf; 146 | set sashelp.cars; 147 | totalsum = sum(of invoice msrp); 148 | run; 149 | 150 | 151 | * sum in proc print; 152 | * this sum the variables , column summation; 153 | proc print data=sumf; 154 | sum invoice msrp; 155 | run; 156 | 157 | 158 | 159 | * factorial, square root, log and log10 functions; 160 | data logfac; 161 | a = 4; 162 | faca = fact(a); 163 | loga = log(a); 164 | log10a = log10(a); 165 | squa = sqrt(a); 166 | run; 167 | 168 | 169 | 170 | 171 | * Input and put functions; 172 | * Remember date is a non-standard numeric variable; 173 | * so length of date is always 8; 174 | data putinp; 175 | input jdate: ddmmyy10,; 176 | format jdate ddmmyy10.; 177 | datalines; 178 | 17/01/2018 179 | ; 180 | run; 181 | 182 | 183 | 184 | * put functions, the length of the resulting variable is same as the format width; 185 | * using input function, the length of the resulting numeric variable will be 8; 186 | * for input function, if not using format for resulting variable, defaults for best12. ; 187 | data newputin; 188 | set putinp; 189 | char = put(jdate, ddmmyy10.); 190 | char2 = put(jdate, date9.); 191 | num = input(char, ddmmyy10.); 192 | run; 193 | 194 | -------------------------------------------------------------------------------- /PrintPro.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical\sql2"; 2 | filename myfolder "C:\Users\Jose\Documents\SasClinical"; 3 | 4 | * print options -- noobs width double heading lable split n ; 5 | * print statements -- id var label by ; 6 | * width can by full or minimium, uniform uniformby (default); 7 | * double give double spacing blw observations; 8 | proc print data=sashelp.class noobs width=full double; 9 | var age sex weight; 10 | run; 11 | 12 | 13 | * heading displays the variable name in a particular orientation -- horizontal or veritcal; 14 | * n print the number of observations at the end of the report; 15 | proc print data=sashelp.class noobs heading=veritcal n; 16 | var age sex weight; 17 | run; 18 | 19 | 20 | * This show changing the obs= print options; 21 | * with sorting; 22 | proc sort data=sasuser.admit out=sortAdmit; 23 | by Age; 24 | run; 25 | 26 | * Without sorting; 27 | proc print data=sasuser.admit (obs=10) obs="Rank"; 28 | run; 29 | 30 | * changing the label of obs, using obs= option; 31 | proc print data=sortAdmit obs="Rank"; 32 | run; 33 | 34 | 35 | 36 | * creating sequence number; 37 | proc sort data=sashelp.class out=class; 38 | by sex; 39 | run; 40 | 41 | * Create sequence number for each by group; 42 | data classsqe; 43 | set class; 44 | by sex; 45 | if first.sex then seqNo = 1; 46 | else seqNo + 1; 47 | run; 48 | 49 | 50 | * Inserting blank lines using blankline= options; 51 | proc print data=sashelp.cars blankline=10 label; 52 | var Make EngineSize Horsepower weight invoice; 53 | title1 "Inserting Blank line"; 54 | title2 "At Every 1oth line"; 55 | label invoice ="Retail Price"; 56 | label make ="Manufacturer"; 57 | run; 58 | 59 | 60 | * Using proc printto; 61 | * This prints the results to external file; 62 | * The first proc printto opens the connection; 63 | proc printto print='myfolder\printto1.txt' 64 | log='myfolder\printto_log.txt'; 65 | run; 66 | 67 | 68 | * print the result of proc print; 69 | proc print data=sashelp.admit; 70 | run; 71 | 72 | 73 | * print the result of proc sql; 74 | * the proc sql select statement is used for printing; 75 | proc sql; 76 | select make origin type invoice 77 | from sashelp.cars; 78 | quit; 79 | * Last proc printto closes the connection; 80 | * without closing, the print output/results are printed to the same file; 81 | proc printto; 82 | run; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jocoder22/SasClinical/66a17f38698eaa9ef3e0db876c69d647a8d7fb43/README.md -------------------------------------------------------------------------------- /Xter_func.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical\functions"; 2 | 3 | 4 | data home.func1; 5 | infile datalines; 6 | input Describe $32.; 7 | datalines; 8 | This is the best eassy 9 | But i have to write more 10 | Letters in this eassy 11 | Are needed just for demo 12 | Have a wonderful day 13 | See you in next session 14 | ; 15 | run; 16 | 17 | 18 | data home.fullname; 19 | infile datalines; 20 | Label Fname="First Name" 21 | Lname="Last Name" 22 | FullName="Full Name"; 23 | length FullName $26; 24 | input Fname :$10. Lname :$12.; 25 | FullName = catx(" ", Fname, Lname); 26 | * can use, call catx(" ", FullName, Fname, Lname); 27 | datalines; 28 | Jose Hargver 29 | Mary Loveensten 30 | Peterson Klevson 31 | Jean Ortgeon 32 | Marleong Bartsisone 33 | Robertson Nowerginma 34 | ; 35 | run; 36 | 37 | 38 | /* Demonstrate case functions*/ 39 | /* Upcase, lowercase, propcase */ 40 | 41 | data caseF; 42 | set home.func1; 43 | desUpper = upcase(Describe); 44 | desLower = lowcase(Describe); 45 | desProper = propcase(Describe); 46 | run; 47 | 48 | 49 | 50 | * Using compress and compbl funtions; 51 | * compbl removes extra blanks, i.e only one blank remaining; 52 | data home.c_comp; 53 | infile datalines; 54 | input name $24.; 55 | datalines; 56 | Jane Easiys 57 | Mark kolwein 58 | Owen Nancy 59 | ; 60 | run; 61 | 62 | * Compress removes specified xter or list of xters; 63 | * if no list or xter specified, compress will remove all blanks; 64 | * if blank is not in specified list, blank will not be removed.; 65 | * Also third, options k=keep, i=ignore case, D=digits, A=alphabets(upper and lower); 66 | * S=space, P=punctuations; 67 | data home.c_comp2; 68 | set home.c_comp; 69 | Name2 = compress(name); 70 | Name3 = compbl(name); 71 | Name4 = lowcase(name); 72 | run; 73 | 74 | proc print data=home.c_comp2; 75 | run; 76 | 77 | data _null_; 78 | string="89-78-nutty Tallty-985_98ktl 98"; 79 | compt=compress(string,"T","i"); 80 | comptA=compress(string,,"A"); 81 | compP=compress(string,,"P"); 82 | compK=compress(string,,"KDS"); *keep digits and space; 83 | comp8=compress(string,"8","KDP"); * third option takes precedence; 84 | put compt= comptA= compP= / compK= comp8=; 85 | run; 86 | 87 | 88 | * Using substr function; 89 | data home.suhu; 90 | set home.c_comp2; 91 | Name5 = Upcase(substr(Name4,1,4)); 92 | Name6 = Upcase(substr(Name4,1,1)); 93 | substr(Name4,5,4) = "AAA"; 94 | run; 95 | 96 | 97 | 98 | * indexw, index, indexc; 99 | * indexw, finds whole word: strings separated by spaces, or space and end/beginging of string; 100 | * index returns the position of the substring while indexc returns position of xter; 101 | data _null_; 102 | header = "World most beautiful island"; 103 | head1 = indexw(header, 'beautiful'); 104 | head2 = indexw(header, 'beauty'); 105 | head3 = indexc(header, "af"); 106 | 107 | put header=; 108 | put head1=; 109 | put head2=; 110 | put head3=; 111 | run; 112 | 113 | 114 | 115 | 116 | * find and findc; 117 | * find returns the positon of a substring; 118 | * findc return the position of a xter; 119 | * The FINDC function searches for individual characters in a character string, 120 | * whereas the FIND function searches for substrings of characters in a character string.; 121 | * findc options includes: k or v to search for xters not in given xter; 122 | * i to ignore case, t to trim trailing blanks 123 | a or A adds alphabetic characters to the list of characters. 124 | b or B searches from right to left, instead of from left to right, 125 | regardless of the sign of the startpos argument. 126 | c or C adds control characters to the list of characters. 127 | d or D adds digits to the list of characters.; 128 | data _null_; 129 | address = "41 Marleong street"; 130 | find1 = find(address, 'Marleong'); 131 | find2 = findc(address, "M"); 132 | 133 | put find1=; 134 | put find2=; 135 | run; 136 | 137 | 138 | 139 | * count, countc; 140 | * count returns the number of occurance of a string; 141 | * countc returns the number of occurances of a xter; 142 | data _null_; 143 | counter = "This is the counter in this history piscis"; 144 | counter1 = count(counter, "is"); 145 | counter2 = countc(counter, 'isc'); 146 | 147 | put counter1=; 148 | put counter2=; 149 | run; 150 | 151 | 152 | * Scan function returns the n-word in a xter expression separated by delimiter; 153 | * if no delimiter specified, then scan function uses the default delimiters; 154 | * ! $ % ^ & * ( ) - + | , blank . / < ; 155 | data home.name(drop=FullName); 156 | set home.fullname(keep FullName); 157 | FirstName = scan(FullName, 1); 158 | LastName = scan(FullName, 2); 159 | run; 160 | 161 | 162 | * Translate function replaces specified xters in a character string; 163 | data _null_; 164 | myword = "Sensitised"; 165 | newword = translate(myword, "z", "s"); 166 | put myword= newword=; 167 | run; 168 | 169 | 170 | * Tranwrd function replace word strings; 171 | * if the string has no length, the Tranw return a length of 200; 172 | * this differs from translate function that replaces xter; 173 | 174 | data home.rolls; 175 | infile datalines; 176 | input states :$12 @@; 177 | OldName = tranwrd(states, "New", "Old"); 178 | datalines; 179 | New York New Jersey New London 180 | New Orleans New Mexico New Jackon 181 | ; 182 | run; 183 | 184 | proc print data=home.rolls; 185 | run; 186 | 187 | 188 | 189 | * length and lengthc function; 190 | * length function returns the length of string excluding trailing blanks; 191 | data _null_; 192 | len6 = "Mango"; 193 | len7 = "Highlander"; 194 | len8 = "Miner and godder"; 195 | lens6L = length(lens6); 196 | lens7L = length(lens7); 197 | lens8L = length(lens8); 198 | put lens6L= lens7L= lens8L=; 199 | run; 200 | 201 | 202 | * lengthc function returns the length of string including the trailing blanks; 203 | data _null_; 204 | length name33 $ 10; 205 | lno = "Johnny "; 206 | name33 = "Klevson"; 207 | name33L = lengthc(name33); 208 | InoL = lengthc(Ino); 209 | put name33L= InoL=; 210 | run; 211 | -------------------------------------------------------------------------------- /array2.sas: -------------------------------------------------------------------------------- 1 | * Rotating long using array; 2 | option validvarname=upcase; 3 | 4 | data cargo; 5 | set sasuser.Y2000; 6 | array crg{*} crgorev1-crgorev6; 7 | do i = 1 to dim(crg); 8 | Revenue = crg{i}; 9 | Harbour = "Harbour" || put(i, z2.); 10 | output; 11 | end; 12 | format Revenue dollar16.2; 13 | drop crgorev1-crgorev6 i; 14 | run; 15 | 16 | proc sort data=cargo out=scargo; 17 | by date; 18 | run; 19 | 20 | 21 | * Rotating wide using array; 22 | data lcargo; 23 | label Date = "RevenueDate"; 24 | array crgorev{6}; 25 | 26 | do i = 1 to dim(crgorev); 27 | set scargo; 28 | by Date; 29 | crgorev(i) = Revenue; 30 | end; 31 | drop i revenue harbour; 32 | run; 33 | 34 | 35 | * Time program for efficiency; 36 | %let starttime = %sysfunc(datetime()); 37 | 38 | * Sas program to time; 39 | * Rotating wide using array; 40 | data lcargo; 41 | label Date = "RevenueDate"; 42 | array crgorev{6}; 43 | 44 | do i = 1 to dim(crgorev); 45 | set scargo; 46 | by Date; 47 | crgorev(i) = Revenue; 48 | end; 49 | drop i revenue harbour; 50 | run; 51 | 52 | %let endtime = %sysfunc(datetime()); 53 | %let duration = %sysfunc(putn(&endtime - &starttime, 8.5)); 54 | 55 | 56 | * write to the log; 57 | data _null_; 58 | put 21*"-" / "Time: &duration seconds" / 21*"-" ; 59 | run; 60 | 61 | 62 | 63 | * Time program for efficiency II; 64 | %let starttime = %sysfunc(datetime()); 65 | 66 | * Sas program to time; 67 | * Rotating wide using proc transpose; 68 | proc transpose data=scargo 69 | out=scargot(drop=_Name_) 70 | prefix=CargoRev; 71 | 72 | var revenue; 73 | by date; 74 | run; 75 | 76 | %let endtime = %sysfunc(datetime()); 77 | %let duration = %sysfunc(putn(&endtime - &starttime, 8.5)); 78 | 79 | * write to the log; 80 | data _null_; 81 | put 21*"-" / "Time: &duration seconds" / 21*"-" ; 82 | run; 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | * Array to calculate total; 91 | * sort dataset cargo; 92 | proc sort data=cargo out=bydate; 93 | by date; 94 | run; 95 | 96 | 97 | proc sort data=cargo out=byharbour; 98 | by Harbour; 99 | run; 100 | 101 | * generate cargo2 dataset; 102 | data cargo2; 103 | set sasuser.Y2000; 104 | array crg{*} crgorev1-crgorev6; 105 | 106 | DailyRevenue = sum( of crg{*}); 107 | TotalRevenue + DailyRevenue; 108 | 109 | format DailyRevenue TotalRevenue dollar22.2; 110 | drop crgorev1-crgorev6; 111 | run; 112 | 113 | 114 | * generate TotalRevenue by date; 115 | data Dbydate; 116 | do until(last.date); 117 | set bydate; 118 | by date; 119 | if first.date then TotalRevenue = 0; 120 | TotalRevenue + Revenue; 121 | end; 122 | format TotalRevenue dollar22.2; 123 | drop Harbour; 124 | run; 125 | 126 | 127 | * Geerate TotalRevenue by Harbour; 128 | data Dbyharbour; 129 | do until(last.Harbour); 130 | set byharbour; 131 | by Harbour; 132 | if first.Harbour then TotalRevenue = 0; 133 | TotalRevenue + Revenue; 134 | end; 135 | format TotalRevenue dollar22.2; 136 | drop date; 137 | run; 138 | 139 | 140 | 141 | * Using sashelp.worker2 dataset; 142 | * Generate the month and year; 143 | data worker2; 144 | set sashelp.workers; 145 | Month = substr(put(date, monyy5.),1,3); 146 | Year = substr(put(date, monyy5.),4,2); 147 | run; 148 | 149 | proc format; 150 | value $mnth "JAN" = 1 "FEB" = 2 "MAR" = 3 "APR" = 4 151 | "MAY" = 5 "JUN" = 6 "JUL" = 7 "AUG" = 8 152 | "SEP" = 9 "OCT" = 10 "NOV" = 11 "DEC" = 12 153 | ; 154 | value mnthv 1 = "JANUARY" 2 = "FEBRUARY" 3 = "MARCH" 155 | 4 = "APRIL" 5 = "MAY" 6 = "JUNE" 156 | 7 = "JULY" 8 = "AUGUST" 9 = "SEPTEMBER" 157 | 10 = "OCTOBER" 11 = "NOVEMBER" 12 = "DECEMBER" 158 | ; 159 | invalue $mnth2b "JAN" = 1 "FEB" = 2 "MAR" = 3 "APR" = 4 160 | "MAY" = 5 "JUN" = 6 "JUL" = 7 "AUG" = 8 161 | "SEP" = 9 "OCT" = 10 "NOV" = 11 "DEC" = 12 162 | ; 163 | run; 164 | 165 | * sort worker2 by month; 166 | proc sort data=worker2 out=bymonth; 167 | by month; 168 | run; 169 | 170 | * sort worker2 by year; 171 | proc sort data=worker2 out=byyear; 172 | by year; 173 | run; 174 | 175 | 176 | 177 | * Generate TotalRevenue by month; 178 | data Dbymonth; 179 | do until(last.date); 180 | set bymonth end=eof; 181 | by month; 182 | if first.date then TotalRevenue = 0; 183 | TotalRevenue + electric + masonry; 184 | end; 185 | GrandTotal + TotalRevenue; 186 | * if eof then output; 187 | run; 188 | 189 | 190 | * Generate TotalRevenue by year; 191 | data Dbyyear; 192 | do until(last.year); 193 | set byyear; 194 | by year; 195 | if first.year then TotalRevenue = 0; 196 | TotalRevenue + electric + masonry; 197 | end; 198 | GrandTotal + TotalRevenue; 199 | run; 200 | 201 | 202 | * Customized sort using proc sql; 203 | proc sql; 204 | create table bymonth2 as 205 | select * , 206 | case (month) 207 | When "JAN" then 1 208 | When "FEB" then 2 209 | When "MAR" then 3 210 | When "APR" then 4 211 | When "MAY" then 5 212 | When "JUN" then 6 213 | When "JUL" then 7 214 | When "AUG" then 8 215 | When "SEP" then 9 216 | When "OCT" then 10 217 | When "NOV" then 11 218 | When "DEC" then 12 219 | else . 220 | end as monthcase 221 | from worker2 222 | order by monthcase; 223 | quit; 224 | 225 | 226 | data Dbymonth2; 227 | do until(last.Month); 228 | set bymonth211(drop=month rename=monthcase=Month); 229 | by Month; 230 | if first.Month then TotalRevenue = 0; 231 | TotalRevenue + electric + masonry; 232 | end; 233 | GrandTotal + TotalRevenue; 234 | format Month mnthv.; 235 | drop year date masonry electric ; 236 | run; 237 | 238 | 239 | /* using proc sql */ 240 | proc sql ; 241 | select sum(electric) as ElectricTotal format=dollar15.2, 242 | sum(masonry) as MasonryTotal format=dollar15.2, 243 | sum(calculated ElectricTotal, calculated MasonryTotal) as GrandTotal format=dollar15.2 244 | from bymonth2; 245 | quit; -------------------------------------------------------------------------------- /arrays.sas: -------------------------------------------------------------------------------- 1 | option validvarname=upcase; 2 | 3 | data patient_visits; 4 | input Name $ (visit1-visit4)(: mmddyy10.); 5 | format visit1-visit4 mmddyy10.; 6 | datalines; 7 | Joe 01/05/2011 01/15/2011 01/25/2011 02/03/2011 8 | Sam 01/07/2011 01/17/2011 01/27/2011 02/10/2011 9 | Ron 01/09/2011 01/19/2011 01/29/2011 03/15/2011 10 | Bob 01/11/2011 01/21/2011 01/31/2011 02/01/2011 11 | ; 12 | run; 13 | 14 | 15 | * Rotate the data to long form; 16 | data long; 17 | set patient_visits; 18 | array visitt{4} visit1-visit4; 19 | do i=1 to dim(visitt); 20 | dateofvisit=visitt{i}; 21 | output; 22 | end; 23 | format dateofvisit mmddyy10.; 24 | drop visit1-visit4 i ; 25 | run; 26 | 27 | 28 | * Rotate to wide form; 29 | * First sort the data; 30 | proc sort data=long out=longsorted; 31 | by name dateofvisit; 32 | run; 33 | 34 | 35 | * Then rotate wide; 36 | data wide; 37 | set longsorted; 38 | by name; 39 | array visit{4}; 40 | retain visit; 41 | if first.name then call missing(of visit[*],i); 42 | i+1; 43 | visit(i)=dateofvisit; 44 | if last.name then output; 45 | format visit : mmddyy10.; 46 | drop dateofvisit i; 47 | run; 48 | 49 | * print wide dataset; 50 | proc print data=wide; 51 | run; 52 | 53 | 54 | 55 | data vs; 56 | label USUBJID = "Unique Subject Indentifier" 57 | VSTESTCD = "Vitals Signs Test Short Name" 58 | VISITNUM = "Visit Number" 59 | VSSTRESN = "Numeric Result/Finding in Standard Units"; 60 | input USUBJID $ VSTESTCD $ VISITNUM VSSTRESN; 61 | datalines; 62 | 101 SBP 1 160 63 | 101 SBP 3 140 64 | 101 SBP 5 150 65 | 101 SBP 6 180 66 | 102 SBP 1 170 67 | 102 SBP 4 190 68 | 102 SBP 6 110 69 | 102 SBP 7 150 70 | 103 SBP 1 169 71 | 103 SBP 4 188 72 | 103 SBP 5 148 73 | 103 SBP 7 159 74 | ; 75 | run; 76 | 77 | * print vs dataset; 78 | proc print data=vs; 79 | run; 80 | 81 | * first sort the dataset; 82 | proc sort data=vs out=vssort; 83 | by usubjid; 84 | run; 85 | 86 | 87 | * Rotate wide; 88 | data wide2; 89 | set vssort; 90 | by usubjid; 91 | keep usubjid visit1-visit7; 92 | retain visit1-visit7; 93 | array sbps {7} visit1-visit7; 94 | 95 | if first.usubjid then 96 | do i=1 to 7; 97 | sbps{i} = .; 98 | end; 99 | sbps(visitnum) = vsstresn; 100 | if last.usubjid; 101 | run; 102 | 103 | 104 | data wide3; 105 | set vssort; 106 | by usubjid; 107 | keep usubjid visit1-visit7; 108 | retain visit1-visit7; 109 | array visit{7}; 110 | if first.usubjid then call missing(of visit[*]); 111 | visit{visitnum}=vsstresn; 112 | if last.usubjid; 113 | run; 114 | 115 | 116 | 117 | * Using do over statement; 118 | * Do over uses index-less array --- remove the { }, but must have element; 119 | data nairavalue5; 120 | set sasuser.Y2000; 121 | array carray _numeric_; 122 | do over carray; 123 | carray = carray * 100; 124 | end; 125 | format crgorev1-crgorev6 dollar20.2; 126 | run; 127 | 128 | proc print data=nairavalue5; 129 | run; 130 | 131 | 132 | -------------------------------------------------------------------------------- /debug.sas: -------------------------------------------------------------------------------- 1 | * Data set debug option is used for programm debugging ; 2 | * this an interactive session the enable programmer to ; 3 | * to discover logic errors - errors the produce unexpected results ; 4 | * Add the data set debugging by using the debug option ; 5 | 6 | data numtt / debug; 7 | set sashelp.class; 8 | if sex="F" then classHeight = Height - mean(Height); 9 | else if sex="M" then classHeight = Height - medium(Height); 10 | else classHeight is missing; 11 | run; 12 | 13 | 14 | * Debugger commands ; 15 | /* 16 | BREAK JUMP 17 | CALCULATE LIST 18 | DELETE QUIT 19 | DESCRIBE SET 20 | ENTER STEP 21 | EXAMINE SWAP 22 | GO TRACE 23 | HELP WATCH 24 | */ 25 | 26 | 27 | * Break is used to set breakpoints, short form is b ; 28 | b 7 ; * breakpoint at line 7; 29 | b 15 after 4 ; * breakpoint at line 15 after every 4 execution of the line; 30 | 31 | 32 | * Calculate used to Calculation involving numeric values, short form calc ; 33 | calc income+expense 34 | calc (payment + tax) * rate 35 | 36 | 37 | 38 | * Delete removes a breakpoint or watch, short form d ; 39 | d b 7; 40 | d w abc; 41 | d b _ALL_ ; 42 | 43 | 44 | 45 | * Describe display the attribute of a variable, short form desc; 46 | desc gender; 47 | desc array{i+k}; 48 | desc treatment; 49 | 50 | 51 | 52 | * Examine display the values of variables. short form ex ; 53 | ex _ALL_; 54 | ex n name 55 | ex trt_date date10. 56 | 57 | 58 | * List displays all occurances of items listed in the argument, short form l ; 59 | l _ALL_; 60 | l w b ; 61 | 62 | 63 | * Go resume the execution of the program, short form g ; 64 | * With argument, it indicate stop line ; 65 | g ; 66 | g 15 ; * go and stop at line 15 ; 67 | 68 | 69 | * Step, execute one statement at a time, use ENTER also ; 70 | * with argument, indicate number of statements to execute ; 71 | step ; 72 | step 5 ; 73 | 74 | 75 | * Jump restarts suspended program ; 76 | * with argument, start at the line or label; 77 | j 45; 78 | 79 | 80 | * Watch suspend execution when the value of specified variable change, alias w; 81 | w orange; 82 | w income; 83 | w salary 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /dictionary.sas: -------------------------------------------------------------------------------- 1 | 2 | * This shows the structure of the dictionary table on the log window ; 3 | proc sql; 4 | describe table dictionary.tables; 5 | quit; 6 | 7 | 8 | * Using sashelp.vtable to show the structure of dictionary table ; 9 | proc sql; 10 | describe view sashelp.vtable; 11 | quit; 12 | 13 | 14 | * describes the structure of data and view ; 15 | proc sql; 16 | select libname, memname, memtype 17 | from dictionary.members 18 | where memtype in ('DATA', 'VIEW') 19 | order by libname asc, memname asc; 20 | quit; 21 | 22 | 23 | * To see the contents of the dictionary ; 24 | proc sql; 25 | create table1 as 26 | select * 27 | from dictionary.dictionary; 28 | quit; 29 | 30 | 31 | 32 | /* This display the libraries and their contents */ 33 | /* this include data, catalog, views, itemstor */ 34 | proc sql; 35 | select * from dictionary.members; 36 | quit; 37 | 38 | 39 | 40 | /* This describles the properties of dataset NNN */ 41 | data mytable; 42 | set sashelp.vtable; 43 | where libname='WORK' and memname='NNN'; 44 | run; 45 | 46 | 47 | 48 | /* This describes the properties of the columns in the table dataset NNN */ 49 | /* this uses data set step */ 50 | data mytableC; 51 | set sashelp.vcolumn; 52 | where libname='WORK' and memname='NNN'; 53 | run; 54 | 55 | 56 | 57 | 58 | /* This describes the properties of the columns in the table dataset NNN */ 59 | /* this uses sql procedure */ 60 | proc sql; 61 | create table mytable2 as 62 | select * from sashelp.vcolumn 63 | where libname='WORK' and memname='NNN'; 64 | quit; 65 | 66 | 67 | 68 | * Describe all dataset, views, catalogs and templates in all libraries ; 69 | proc sql; 70 | create table mytable3 as 71 | Select * from dictionary.dictionaries; 72 | quit; 73 | 74 | 75 | 76 | /* This displays the occurances of column names in libnames except maps and sashelp */ 77 | proc sql; 78 | select name, count(*) as Frequency 79 | from dictionary.columns where libname not in ('MAPS', 'SASHELP') 80 | group by name 81 | having count(*) > 1 82 | order by Frequency DESC; 83 | quit; 84 | 85 | 86 | 87 | * display number of observations in all dataset in libname sashelp and sasuser ; 88 | proc sql; 89 | select libname, memname, nobs 'Number of Observations' 90 | from dictionary.tables 91 | where libname in ('SASHELP', 'SASUSER') 92 | order by nobs desc; 93 | quit; -------------------------------------------------------------------------------- /doloop.sas: -------------------------------------------------------------------------------- 1 | data loan1; 2 | grossloan = 299900; 3 | downpayment = 14695; 4 | monthlypay = 2144; 5 | interest = 0.04543; 6 | netloan = grossloan - downpayment; 7 | do year = 1 to 30; 8 | do month = 1 to 12; 9 | netloan = netloan - monthlypay; 10 | totalpayment + monthlypay; 11 | end; 12 | netloan = netloan + (netloan * interest); 13 | end; 14 | loan = netloan; 15 | run; 16 | 17 | 18 | 19 | data mortage(drop=netloan downpayment); 20 | grossloan = 299900; 21 | downpayment = 14695; 22 | monthlypay = 2144; 23 | interest = 0.04543; 24 | netloan = grossloan - downpayment; 25 | 26 | do while(netloan ge 0); 27 | year + 1; 28 | do month = 1 to 12 while(netloan ge 0); 29 | netloan = netloan - monthlypay; 30 | totalpayments + monthlypay; 31 | end; 32 | netloan = netloan + (netloan * interest); 33 | end; 34 | loan = netloan; 35 | run; 36 | 37 | proc print data=loan1; 38 | run; 39 | 40 | 41 | data mortageCalc(keep= time monthlypay total); 42 | pAndi = 2154; 43 | tax = 565; 44 | insurance = 57; 45 | HOAFees = 374; 46 | time = 10 * 12; 47 | monthlypay = pAndi + insurance + tax + HOAFees; 48 | do i = 1 to time; 49 | Total + monthlypay; 50 | end; 51 | run; -------------------------------------------------------------------------------- /formats.sas: -------------------------------------------------------------------------------- 1 | libname library "C:\Users\Jose\Documents\SasClinical"; 2 | filename myformat "C:\Users\Jose\Documents\SasClinical\formats"; 3 | 4 | 5 | 6 | * Creating user defined formats; 7 | proc format library=library; 8 | value $gender "F" = "Female" 9 | "M" = "Male" 10 | ; 11 | value &gen "F" = 1 "M" = 2 ; 12 | value agegrp 11 - 12 = "Young" 13 | 13 - 14 = "Middle" 14 | 15 - high = "Old" 15 | ; 16 | run; 17 | 18 | 19 | * Using format, first use the fmtsearch option to link to the libname; 20 | options fmtsearch=(library); 21 | 22 | proc print data=sashelp.class; 23 | format sex $gender. age agegrp. ; 24 | run; 25 | 26 | 27 | * printing the content of a format library; 28 | proc format library=library fmtlib; 29 | run; -------------------------------------------------------------------------------- /gplots.sas: -------------------------------------------------------------------------------- 1 | * Non graphical plot; 2 | proc plot data=sashelp.class; 3 | plot age*height; 4 | run; 5 | quit; 6 | 7 | proc plot data=sashelp.class; 8 | plot age*height="*"; 9 | run; 10 | quit; 11 | 12 | * Graphical plots; 13 | proc gplot data=sashelp.class; 14 | plot age*height; 15 | run; 16 | quit; 17 | 18 | 19 | * Different groups on the same graph; 20 | proc gplot data=sashelp.class; 21 | plot age*height=sex; 22 | run; 23 | quit; 24 | 25 | 26 | * Add custom colors and symbols; 27 | symbol1 color=green value=circle height=2; 28 | symbol2 color=red value=star height=2; 29 | 30 | proc gplot data=sashelp.class; 31 | plot age*height=sex; 32 | run; 33 | quit; 34 | 35 | 36 | * Advanced plots using sgplots; 37 | * the HTML output is the default ODS; 38 | * scatter, series, step and box plots; 39 | proc sgplot data=sashelp.class; 40 | scatter x=height y=weight; 41 | run; 42 | quit; 43 | 44 | 45 | * change marker attributes; 46 | proc sgplot data=sashelp.class; 47 | scatter x=height y=weight/ markerattrs=(symbol=star size=6); 48 | run; 49 | quit; 50 | 51 | 52 | * Use series sgplot to produce joined points; 53 | proc sgplot data=sashelp.class; 54 | series x=height y=weight; 55 | run; 56 | quit; 57 | 58 | * change line attributes; 59 | proc sgplot data=sashelp.class; 60 | series x=height y=weight / lineattrs=(color=red thickness=4); 61 | run; 62 | quit; 63 | 64 | * combining multiple lines on one plot; 65 | proc sgplot data=sashelp.class; 66 | series x=name y=weight / lineattrs=(color=red thickness=4); 67 | series x=name y=height / lineattrs=(color=green thickness=4); 68 | run; 69 | quit; 70 | 71 | 72 | * step plot; 73 | proc sgplot data=sashelp.class; 74 | step x=name y=weight / lineattrs=(color=red thickness=4); 75 | run; 76 | quit; 77 | 78 | proc sgplot data=sashelp.class; 79 | step x=name y=weight / lineattrs=(color=red thickness=4); 80 | step x=name y=height / lineattrs=(color=green thickness=4); 81 | run; 82 | quit; 83 | 84 | 85 | * Box plots: vbox, hbox; 86 | proc sgplot data=sashelp.class; 87 | vbox age / category=sex; 88 | run; 89 | quit; 90 | 91 | proc sgplot data=sashelp.class; 92 | vbox age / category=sex; 93 | run; 94 | quit; 95 | 96 | * sgplot vbar, hbar; 97 | proc sgplot data=sashelp.class; 98 | vbar age / group=sex response=height stat=mean; 99 | run; 100 | quit; 101 | 102 | proc sgplot data=sashelp.class; 103 | hbar age / group=sex response=height stat=mean; 104 | run; 105 | quit; 106 | 107 | 108 | 109 | proc template; 110 | define style newblue / store=work.templ; 111 | parent=styles.htmlblue; 112 | 113 | class graph / attrpriority='none'; 114 | class GraphData1 / markersymbol="circle" contrastcolor=black; 115 | class GraphData2 / markersymbol="star" contrastcolor=black; 116 | 117 | end; 118 | run; -------------------------------------------------------------------------------- /graphs.sas: -------------------------------------------------------------------------------- 1 | * Vbar uses freq statistics as default; 2 | * Without discrete uses the mid-point for the values; 3 | proc chart data=sashelp.class; 4 | vbar age; 5 | run; 6 | quit; 7 | 8 | 9 | 10 | * With discrete option, the exact values are used; 11 | proc chart data=sashelp.class; 12 | vbar age / discrete; 13 | run; 14 | quit; 15 | 16 | 17 | * Using the graphical charts, gcharts; 18 | * this is more colorful and clearer; 19 | proc gchart data=sashelp.class; 20 | vbar age; 21 | run; 22 | quit; 23 | 24 | * change statistics from freq to percent using type option; 25 | proc gchart data=sashelp.class; 26 | vbar age/ discrete type=percent; 27 | run; 28 | quit; 29 | 30 | 31 | * using sumvar to get summary variable, i.e the y-axis; 32 | * Here we find the average(mean) height for each discrete age; 33 | * mean option displays the values on top of each bar; 34 | proc gchart data=sashelp.class; 35 | vbar age / discrete type=mean sumvar=height mean; 36 | run; 37 | quit; 38 | 39 | 40 | * use the group option for categorical groups 41 | * this displays chart for each group on the same graph; 42 | proc gchart data=sashelp.class; 43 | vbar age / discrete type=mean sumvar=height mean group=sex; 44 | run; 45 | quit; 46 | 47 | * subgroup= option stack the groups on top of each other; 48 | proc gchart data=sashelp.class; 49 | vbar age / discrete type=mean sumvar=height mean subgroup=sex; 50 | run; 51 | quit; 52 | 53 | * To get the group graphs on separate pages/output; 54 | * use the by statement, after sorting the data; 55 | proc sort data=sashelp.class; 56 | sort by sex; 57 | run; 58 | 59 | proc gchart data=sashelp.class; 60 | vbar age / discrete type=mean sumvar=height mean; 61 | by sex; 62 | run; 63 | quit; 64 | 65 | 66 | * Subsetting the data using where statement; 67 | proc gchart data=sashelp.class; 68 | vbar age / discrete type=mean sumvar=height mean; 69 | where sex="M" and age in (11 14 15); 70 | run; 71 | quit; 72 | 73 | 74 | * using 3D graphs, vbar3d; 75 | proc gchart data=sashelp.class; 76 | vbar3d age / discrete type=mean sumvar=height mean; 77 | where sex="M"; 78 | run; 79 | quit; 80 | 81 | * other 3D options like shapes= cylinder, prism, star, block, hexagon; 82 | * patternid to change the color and width to change the width of the 3D shapes; 83 | proc gchart data=sashelp.class; 84 | vbar3d age / discrete type=mean sumvar=height mean shape=cylinder width=20 patternid=midpoint; 85 | where sex="M"; 86 | run; 87 | quit; 88 | 89 | 90 | * Hbars; 91 | * Hbars will give default freq statistics in addition to the graph; 92 | proc gchart data=sashelp.class; 93 | hbar age / discrete; 94 | where sex="M"; 95 | run; 96 | quit; 97 | 98 | 99 | * Pie charts; 100 | proc gchart data=sashelp.class; 101 | pie age / discrete type=mean sumvar=height mean; 102 | where sex="M"; 103 | run; 104 | quit; 105 | 106 | proc gchart data=sashelp.class; 107 | pie3d age / discrete type=mean sumvar=height mean; 108 | where sex="M"; 109 | run; 110 | quit; 111 | 112 | 113 | * values inside keep the values(mean) inside the pie; 114 | * slice inside keeps the variables inside the pie; 115 | proc gchart data=sashelp.class; 116 | pie3d age / discrete type=mean sumvar=height mean values=inside slice=inside; 117 | where sex="M"; 118 | run; 119 | quit; 120 | 121 | 122 | * Donut, star and block graphs; 123 | proc gchart data=sashelp.class; 124 | donut age / discrete type=mean sumvar=height mean; 125 | where sex="M"; 126 | run; 127 | quit; 128 | 129 | proc gchart data=sashelp.class; 130 | star age / discrete type=mean sumvar=height mean; 131 | where sex="M"; 132 | run; 133 | quit; 134 | 135 | proc gchart data=sashelp.class; 136 | block age / discrete type=mean sumvar=height mean; 137 | where sex="M"; 138 | run; 139 | quit; 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /im_export.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical"; 2 | %let folder =/folders/myshortcuts/SasClinical; 3 | %let exfold =/folders/myshortcuts/SasClinical/I_Export; 4 | 5 | /* Importing data/files using Proc import*/ 6 | /* Import excell file*/ 7 | * datarow is used to select specific number of observations; 8 | proc import out=home.mydata 9 | datafile="&folder/mydata.xls" 10 | dbms=xls replace; 11 | getnames=no; 12 | sheet=Test; 13 | datarow=8; 14 | run; 15 | 16 | 17 | /* Import sheet range */ 18 | * Don't use sheet= when using range, range= will have reference to the sheet ; 19 | proc import out=home.mydataRange 20 | datafile="&folder/mydata.xls" 21 | dbms=xls replace; 22 | getnames=no; 23 | range='Test$A1:F22'; 24 | run; 25 | 26 | 27 | /* Importing Microsoft Access Table */ 28 | proc import datatable=Flight 29 | out=home.flight 30 | dbms=access replace; 31 | database="&folder/acs.mdb"; 32 | run; 33 | 34 | 35 | proc import table=Flight 36 | out=home.flight2 37 | dbms=access replace; 38 | database="&folder/acs.mdb"; 39 | run; 40 | 41 | 42 | 43 | /* Import cvs file */ 44 | proc import datafile="&folder/mydata.cvs" 45 | out=home.mycvs 46 | dbms=cvs replace; 47 | getnames=no; 48 | run; 49 | 50 | 51 | 52 | /* Import other delimited file */ 53 | * others dbms = tab ; 54 | proc import datafile="&folder/mydata22.txt" 55 | out=home.mytext 56 | dbms=dlm replace; 57 | delimiter=" "; 58 | getnames=no; 59 | run; 60 | 61 | 62 | 63 | /* Exporting files */ 64 | * exporting to text file; 65 | proc export outfile="&folder/mycars.txt" 66 | data=sashelp.cars 67 | dbms=dlm replace; 68 | delimiter=" "; 69 | run; 70 | 71 | 72 | * exporting to text file; 73 | * exporting to csv file; 74 | proc export outfile="&folder/mycars2.csv" 75 | data=sashelp.cars 76 | dbms=csv replace; 77 | delimiter=" "; 78 | run; 79 | 80 | 81 | * Expoting to excell file; 82 | proc export outfile="&folder/Excars.xlsx" 83 | data=sashelp.cars 84 | dbms=xlsx replace; 85 | run; 86 | 87 | /* Exporting Access files */ 88 | proc export outtable=cars 89 | data=sashelp.cars 90 | dbms=access; 91 | database="&folder/Accesscars.mdb"; 92 | run; -------------------------------------------------------------------------------- /listing.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical"; 2 | %let mylst=C:\Users\Jose\Documents\SasClinical\listing; 3 | 4 | 5 | data old; 6 | infile datalines; 7 | input ID $ Sex $ Race $ Age Ageu $; 8 | datalines; 9 | 101 M Asian 35 years 10 | 102 M Europe 48 years 11 | 103 F African 45 years 12 | 104 M Asian 39 years 13 | 105 F Chinese 32 years 14 | 106 F Asian 30 years 15 | ; 16 | run; 17 | 18 | 19 | 20 | * In listing, we generate a listing output. No statistics is calculated; 21 | data new; 22 | set old; 23 | col1 = strip(id)||'/'||strip(sex)||'/'||strip(race); 24 | * can use catx(/, id, sex, race;) 25 | col2 = strip(put(age,2.))||'/'||strip(ageu); 26 | keep col1 col2; 27 | title "Listing of Demographic Data"; 28 | run; 29 | title; 30 | 31 | 32 | * listing using sql; 33 | proc sql; 34 | create table advs1 as 35 | select l.usubjid, l.trtp, l.trtpn, l.avisitn, l.avisit, l.param, l.aval, 36 | r.country, r.sex, r.age from sasuser.advs as l left join sasuser.ads1 as r 37 | on l.usubjid=r.usubjid; 38 | quit; 39 | 40 | 41 | optiions ls=200 nocenter nodata nonumber; title; 42 | proc format; 43 | value $gender 'M'='Male' 'F' = 'Female'; 44 | run; 45 | 46 | 47 | proc printto print="&mylst/report1.txt" 48 | log="&mylst/report1_log.txt" 49 | run; 50 | 51 | 52 | proc report data=advs1 nowd headskip headline split='*'; 53 | column ('--' usubjid sex country age trtpn trtp param avisitn avisit aval); 54 | define param/width=35 order; 55 | define usubjid / 'Subject*Identifier' order; 56 | define sex / group format=$gender.; 57 | define country/ order width=10; 58 | define age/ order; 59 | define trtpn/ noprint order; 60 | define trtp/ order; 61 | define avisitn/ noprint order; 62 | define avisit/ order; 63 | compute before _page_; 64 | line @10 'BP3304-002' @120 'l_vitals.sas'; 65 | line ''; line ''; 66 | line @40 'Subject Vitals Signs information - listing'; 67 | line ''; 68 | endcomp; 69 | compute after; 70 | line @2 135*'-'; line ''; 71 | line @2 'Note: Sorted treatment group'; 72 | endcomp; 73 | quit; 74 | 75 | proc printto; 76 | run; 77 | 78 | 79 | * In tables we generate statistics; 80 | -------------------------------------------------------------------------------- /listing2.sas: -------------------------------------------------------------------------------- 1 | ******************************************************************** 2 | * Program name: 3 | * Output name: t_demog 4 | * Programmer: 5 | * Date: 6 | * Reviewer: 7 | * Review Date: 8 | * Title: 9 | ********************************************************************* 10 | 11 | * Double the entire data to generate the value holder for the overall data; 12 | * This is based on the new overall treatment group, with value 9; 13 | data demog; 14 | set sasuser.demog; 15 | output; * this output original data; 16 | trt = 9; * this generate value holder for overall group; 17 | output; * this add the overall treatment group per observation; 18 | run; 19 | 20 | 21 | 22 | * sort the data by treatment groups; 23 | proc sort data=demog; 24 | by trt; 25 | run; 26 | 27 | 28 | 29 | * Generate age statistics by treatment groups; 30 | proc summary data=demog; 31 | by trt; 32 | var age; 33 | output out=age1 n=_N mean=_mean st=_std median=_mdn min=_mn max=_mx; 34 | run; 35 | 36 | 37 | 38 | * Concatenate variable; 39 | data age2; 40 | set age1; 41 | meansd = put(_mean,4.1)||'('||put(_std,5.2)||')'; 42 | mnmx = put(_mn,3.0)||','||put(_mx,3.0); 43 | N = put(_n,3.0); 44 | median = put(_mdn,4.1); 45 | drop _:; 46 | run; 47 | 48 | 49 | 50 | * Transpose data; 51 | proc transpose data=age2 out=age3; 52 | id trt; 53 | var n meansd median mnmx; 54 | run; 55 | 56 | 57 | * Generate values for _name_; 58 | data age4; 59 | length newvar$ 30.; 60 | set age3; 61 | if _name_ = 'N' then newvar=' N'; 62 | else if _name_ = 'meansd' then newvar=' Mean(SD)'; 63 | else if _name_ = 'median' then newvar=' Median'; 64 | else if _name_ = 'mnmx' then newvar=' Min,Max'; 65 | drop _name_; 66 | run; 67 | 68 | 69 | data dummy; 70 | length newvar$ 30.; 71 | newvar = 'Age(years)'; 72 | run; 73 | 74 | data age; 75 | set dummy age4; 76 | ord = 1; 77 | run; 78 | 79 | 80 | 81 | 82 | 83 | * Gender statistics; 84 | proc freq data=demog noprint; 85 | by trt; 86 | table gender/out=gen1; 87 | where gender ne .; 88 | run; 89 | 90 | 91 | data gen2; 92 | set gen1; 93 | np = put(count,3.0)||'('||put(percent,4.1)||')'; 94 | run; 95 | 96 | proc sort data=gen2; 97 | by gender; 98 | run; 99 | 100 | 101 | proc transpose data=gen2 out=gen3; 102 | id trt; 103 | var np; 104 | by gender; 105 | run; 106 | 107 | data gen4; 108 | length newvar$ 30.; 109 | set gen3; 110 | if gender=1, the newvar=' Male'; 111 | else if gender=2 then newvar=' Female'; 112 | drop gender _name_; 113 | run; 114 | 115 | 116 | data dummy; 117 | length newvar$ 30.; 118 | newvar='Gender[n(%)]'; 119 | run; 120 | 121 | data gender; 122 | set dummy gen4; 123 | ord=2; 124 | run; 125 | 126 | 127 | 128 | 129 | * Ethnic statistics; 130 | proc freq data=demog noprint; 131 | by trt; 132 | table ethnic/out=ethnic1; 133 | where ethnic ne .; 134 | run; 135 | 136 | 137 | data ethnic2; 138 | set ethnic1; 139 | np = put(count,3.0)||'('||put(percent,4.1)||')'; 140 | run; 141 | 142 | proc sort data=ethnic2; 143 | by ethnic; 144 | run; 145 | 146 | 147 | proc transpose data=ethnic2 out=ethnic3; 148 | id trt; 149 | var np; 150 | by ethnic; 151 | run; 152 | 153 | data ethnic4; 154 | length newvar$ 30.; 155 | set gen3; 156 | if ethnic=1, the newvar=' Hispanic or Latino'; 157 | else if ethnic=2 then newvar=' Not Hispanic or Latino'; 158 | drop ethnic _name_; 159 | run; 160 | 161 | 162 | data dummy; 163 | length newvar$ 30.; 164 | newvar='Ethnicity[n(%)]'; 165 | run; 166 | 167 | data ethnic; 168 | set dummy ethnic4; 169 | ord=3; 170 | run; 171 | 172 | 173 | 174 | 175 | * Race statistics; 176 | proc freq data=demog noprint; 177 | by trt; 178 | table Race/out=Race1; 179 | where Race ne .; 180 | run; 181 | 182 | 183 | data Race2; 184 | set Race1; 185 | np = put(count,3.0)||'('||put(percent,4.1)||')'; 186 | run; 187 | 188 | proc sort data=Race2; 189 | by Race; 190 | run; 191 | 192 | 193 | proc transpose data=Race2 out=Race3; 194 | id trt; 195 | var np; 196 | by Race; 197 | run; 198 | 199 | data Race4; 200 | length newvar$ 30.; 201 | set Race3; 202 | if Race=1, the newvar=' White'; 203 | else if Race=2 then newvar=' Black or African American'; 204 | else if Race=3 then newvar=' Asian'; 205 | drop Race _name_; 206 | run; 207 | 208 | 209 | data dummy; 210 | length newvar$ 30.; 211 | newvar='Race[n(%)]'; 212 | run; 213 | 214 | data Race; 215 | set dummy Race4; 216 | ord=4; 217 | run; 218 | 219 | 220 | * Final dataset; 221 | data final; 222 | set age gender ethnic race; 223 | run; 224 | 225 | 226 | * Creating the final report; 227 | options nocenter nodate nonumber; title; 228 | proc report data=final nowd headline headskip split='*'; 229 | column('--' ord newvar _0 _1 _9); 230 | define ord/ order noprint; 231 | break after ord/ skip; 232 | define newvar/ ''; 233 | define _1/ 'BP3304*(N=31)'; 234 | define _0/'Placebo*(N=29)'; 235 | define _9/'Overall*(N=60)'; 236 | compute before _page_; 237 | line @10 '14.1.2.1 Subject Demographics and baseline characteristics'; 238 | line @40 'Safety Population'; 239 | endcomp; 240 | compute before _page_; 241 | line @2 70*'-'; 242 | line @3 'Reference: Listing 16.4.2.1'; 243 | line @5 'Percentages are based on the number of subjects in the Population'; 244 | line @3 'Note: SD = standard deviation, Min = Minimum, Max = Maximum'; 245 | endcomp; 246 | run; 247 | 248 | -------------------------------------------------------------------------------- /listing3.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical"; 2 | %let mylls=C:\Users\Jose\Documents\SasClinical\listing3; 3 | 4 | 5 | * Listing using macros; 6 | * First double the dataset; 7 | data adsl; 8 | set home.adsl; output; 9 | trt01an=9; output; 10 | run; 11 | 12 | 13 | 14 | 15 | %macro listtm(var=, title=, num=); 16 | proc summmary data=adsl; 17 | class trt01an; 18 | var &var.; 19 | output out=&var._1 (where=(trt01an ne .)) 20 | n=_n mean=_mean std=_std median=_median min=_mn max=_mx; 21 | run; 22 | 23 | 24 | data &var._2; 25 | set &var._1; 26 | meansd=put(_mean,4.1)||'('||put(_std,5.2)||')'; 27 | mnmx=put(_mn,3.0)||','||put(_mx,3.0); 28 | n=put(_n,3.0); 29 | median=put(_median,4.1); 30 | drop _:; 31 | run; 32 | 33 | 34 | proc transpose data=&var._2 out=&var._3; 35 | id trt01an; 36 | var n meansd median mnmx; 37 | run; 38 | 39 | 40 | 41 | data &var._4; 42 | length newvar$ 30.; 43 | set &var._3; 44 | if _name_='n' then newvar=' N'; 45 | else if _name_='meansd' then newvar=' Mean(SD)'; 46 | else if _name_='mnmx' then newvar=' Min, Max'; 47 | else if _name_='median' then newvar=' Median'; 48 | drop _name_; 49 | run; 50 | 51 | 52 | data dummy; 53 | length newvar$ 30.; 54 | newvar=&title; 55 | run; 56 | 57 | 58 | data &var.; 59 | set dummy &var._4; 60 | ord=# 61 | run; 62 | 63 | 64 | proc dataset lib=work nolist; 65 | delete &var._: dummy; 66 | quit; 67 | run; 68 | %mend; 69 | 70 | 71 | 72 | * Calling the macro; 73 | * Calling macro for height statistics; 74 | %listtm(var=height,title="Height(cm)",num=1); 75 | 76 | * Calling macro for weight statistics; 77 | %listtm(var=weight,title="Weight(kg)",num=2); 78 | 79 | * Calling macro for BMI statistics; 80 | %listtm(var=bmi,title="Body Mass Index(kg/m^2)",num=3); 81 | 82 | 83 | 84 | * Final dataset; 85 | data final; 86 | set height weight bmi; 87 | run; 88 | 89 | proc sql noprint; 90 | select count(distinct subjid) into: N1-: N3 from adsl 91 | group by trt01an; 92 | quit; 93 | 94 | options nodate nonumber nocenter; title; 95 | proc printto print="mylls/report3.txt"; 96 | run; 97 | 98 | 99 | proc report data=final nowd headskip headline skip='*'; 100 | column ('--' ord newvar _1 _0 _9); 101 | define ord/order noprint; 102 | break after ord/skip; 103 | define newvar/''; 104 | define _1/"BP3304*(N=&n2)"; 105 | define _0/"Placebo*(N=&n1)"; 106 | define _9/"Overall*(N=&n3)"; 107 | compute afte; 108 | @2 72*'_'; 109 | endcomp; 110 | run; 111 | 112 | proc printto; 113 | run; -------------------------------------------------------------------------------- /listing4.sas: -------------------------------------------------------------------------------- 1 | libname report4 "C:\Users\Jose\Documents\SasClinical"; 2 | %let myrp4=C:\Users\Jose\Documents\SasClinical\listing4; 3 | 4 | 5 | * Double the dataset; 6 | data admin; 7 | set report4.admin1; output; 8 | trt=9; output; 9 | run; 10 | 11 | 12 | data left; 13 | length label$ 50.; 14 | ord=1; label='No. of subjects who completed Treatment'; output; 15 | ord=2; label='No. of subjects who discontinued Treatment'; output; 16 | ord=3; sord=0; label=' Reasons for discontinuation:'; output; 17 | ord=3; sord=1; label=' Adverse Event'; output; 18 | ord=3; sord=2; label=' Lack of Efficacy'; output; 19 | ord=3; sord=3; label=' Lost to Followup'; output; 20 | ord=3; sord=4; label=' Withdrew Consent'; output; 21 | ord=3; sord=5; label=' Adminstrative'; output; 22 | ord=3; sord=6; label=' Protocol Violation'; output; 23 | run; 24 | 25 | 26 | proc sql; 27 | create table count as 28 | select count(distinct subjid) as n, trt, 1 as ord from admin 29 | where complyn=1 group by trt 30 | union all 31 | select count(distinct subjid) as n, trt, 2 as ord from admin 32 | where complyn=2 group by trt 33 | union all 34 | select count(distinct subjid) as n, trt, 3 as ord, discn as sord from admin 35 | where complyn=2 group by trt, discn 36 | order by trt; 37 | quit; 38 | 39 | proc sql; 40 | create table demon as 41 | select count(distinct subjid) as bign, trt from admin 42 | group by trt; 43 | order by trt; 44 | quit; 45 | 46 | 47 | data new; 48 | merge count denom; 49 | by trt; 50 | np=put(n,3.0)||'('||put((n/bign)*100,4.1)||')'; 51 | run; 52 | 53 | proc sort data=new; 54 | by ord sord; 55 | run; 56 | 57 | proc transpose data=new out new1; 58 | id trt; 59 | var np; 60 | by ord sord; 61 | run; 62 | 63 | 64 | proc sort data=left; 65 | by ord sord; 66 | run; 67 | 68 | proc sort data=new1; 69 | by ord sord; 70 | run; 71 | 72 | data final; 73 | merge left new1; 74 | by ord sord; 75 | run; 76 | -------------------------------------------------------------------------------- /macro2.sas: -------------------------------------------------------------------------------- 1 | * Debugging II ; 2 | * using symlocal and symglobl to search for macro variable scope ; 3 | * declare macro variable scope, they have null values upon declaration ; 4 | %global lane Road; 5 | %local Apt Room; 6 | 7 | * search for scope, returns 1 if found in global symbol table and Zero otherwise ; 8 | %put %symglobl(lane); 9 | %put %symglobl(Apt) 10 | 11 | 12 | * search for scope, returns 1 if found in local symbol table and Zero otherwise ; 13 | %put %symlocal(Road); 14 | %put %symlocal(Room); 15 | 16 | 17 | * Using %local to restrict macro variable changes to within the macro that defined the variable ; 18 | * it also create a local macro variable in the local symbol table ; 19 | * local variable is not valid on the open code, i.e cand declare %local outside the macro ; 20 | 21 | %let cityname = New York; 22 | %macro demo(name); 23 | %local cityname; 24 | %let cityname = &name; 25 | %put The name of the city is &name; 26 | %mend; 27 | 28 | %demo(Baltimore); 29 | %put After demo execution the name of the city is &cityname; 30 | 31 | 32 | * Using %global for global declaration ; 33 | %global dance; 34 | %let dance = DoggleHog; 35 | 36 | %macro dancing(d1, d2); 37 | %global dance2; 38 | %let dance2 = Boggie; 39 | %put Please start with &dance and then followed by &dance2; 40 | %put Then do &d1 and finally &d2 , Thanks; 41 | %mend; 42 | 43 | %dancing(Reggae, HipPop); 44 | 45 | 46 | * Can call global macro variable even outside the macro definition ; 47 | %put Which dance is &dance2.?; 48 | 49 | * search for dance2 macro variable ; 50 | %put %symglobl(dance2); 51 | %put %symlocal(dance2); 52 | 53 | 54 | * Mfile is used to direct the mprint output to external file ; 55 | * First you must name the fileref mprint ; 56 | options mfile mlogic mprint 57 | filename mprint "C:/mymacro/outprint.txt" 58 | 59 | 60 | 61 | * resolve is used to assign result of macro functon to a variable ; 62 | %let joy = joyfull Praise; 63 | data hootte; 64 | bogge = resolve('&joy'); 65 | bogge2 = resolve('%dancing(Reggae, Ogone'); 66 | %put bogge = bogg2 = ; 67 | run; 68 | -------------------------------------------------------------------------------- /macros.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical"; 2 | filename myfile2 "C:\Users\Jose\Documents\SasClinical\macros"; 3 | 4 | %let a=sashelp.class; 5 | 6 | proc print data=&a; 7 | run; 8 | 9 | 10 | data class1; 11 | set &a; 12 | run; 13 | 14 | 15 | %put &a; * print to log; 16 | 17 | %let a=1; 18 | %let b=2; 19 | %let c=3.5; 20 | %let d=8.3; 21 | 22 | 23 | %put &a+&b; 24 | %put %eval(&a+&b); * eval() convert values to their integer value, works on integers only; 25 | %put %sysevalf(&c+&d); * syseval() works on floating numbers; 26 | 27 | 28 | 29 | * Creating macros; 30 | %macro printme; 31 | proc print data=sashelp.class; 32 | run; 33 | %mend; 34 | 35 | %printme; 36 | 37 | * macro with keyword parameter; 38 | * the named keyword automatically becomes a macro variable; 39 | %macro printed(dtname=); 40 | proc print data=&dtname; 41 | run; 42 | %mend; 43 | 44 | %printed(dtname=sashelp.class); 45 | 46 | %macro dtcreat(new=, old=, var=, val=); 47 | data &new; 48 | set &old; 49 | where &var=&val; 50 | run; 51 | %mend; 52 | 53 | * keyword parameters; 54 | %macro sort(dset=, new=, byvar=); 55 | proc sort data=&dset out=&new; 56 | by &byvar; 57 | run; 58 | %mend; 59 | 60 | %sort(dset=sashelp.class, new=class1, byvar=age); 61 | 62 | 63 | 64 | * Positional parameters; 65 | * the positional parameter must be listed according to their positions; 66 | %macro sorted(dset1, new1, byvar1); 67 | proc sort data=&dset1 out=&new1; 68 | by &byvar1; 69 | run; 70 | %mend; 71 | 72 | %sorted(sashelp.class, class2, sex); 73 | 74 | 75 | * Using keyword parameter is the standard; 76 | * the parameters can be listed in any order; 77 | %macro multi(cond=, old=, new=, byvar=, tvar=, avar=); 78 | %if &cond=S %then %do; 79 | proc sort data=&old out=&new; 80 | by &byvar; 81 | run; 82 | %end; 83 | %if &cond=F %then %do; 84 | proc freq data=&new; 85 | by &byvar; 86 | table &tvar; 87 | run; 88 | %end; 89 | %if &cond=M %then %do; 90 | proc means data=&new; 91 | by &byvar; 92 | var &avar; 93 | run; 94 | %end; 95 | %if &cond=P %then %do; 96 | proc print data=&new; 97 | run; 98 | %end; 99 | %mend; 100 | 101 | 102 | %multi(cond=S, old=sashelp.class, new=class4, byvar=sex); 103 | %multi(cond=S, old=sasuser.blood, new=blood, byvar=gender); 104 | %multi(cond=F, new=class4, byvar=sex, tvar=age); 105 | %multi(cond=M, new=blood, byvar=gender, avar=rbc); 106 | 107 | 108 | %macro looped(dtname=); 109 | %let i=1; 110 | %do %while (&i le 4); 111 | %let dset=%scan(&dtname, &i); 112 | proc print data=&dset; 113 | run; 114 | %let i=%eval(&i+1); 115 | %end; 116 | %mend; 117 | 118 | 119 | %looped(dtname=sashelp.class sasuser.blood sashelp.cars sashelp.housing); 120 | 121 | 122 | * Macro interface functions; 123 | * uses data set functions in macro programs; 124 | %let a = This is sas; 125 | %let b = This is_sas; 126 | %put %length(&a); 127 | %put %scan(&a, 1); 128 | 129 | %put %sysfunc(countw(&a)); 130 | %put %sysfunc(scan(&b, 1, %str(_))); 131 | 132 | 133 | * creating macro variables using symput, symputx and symget; 134 | %let AgeAveg = 21; 135 | data _null_; 136 | set sashelp.class; 137 | if name = "Jane" then do; 138 | call symputx('janeAge', age); 139 | call symput('janeDept', dept); 140 | end; 141 | Agedev = age - symget(AgeAveg); 142 | run; 143 | 144 | 145 | 146 | * Using sql to create macros; 147 | 148 | proc sql; 149 | select name into: mvarf 150 | from sashelp.class; 151 | quit; 152 | 153 | 154 | * the variable values are separated by space; 155 | proc sql noprint; 156 | select name into: mvar separated by ' ' 157 | from sashelp.class; 158 | quit; 159 | 160 | %put &mvar; 161 | %put %sysfunc(scan(&mvar, 12)); 162 | 163 | 164 | * This forms a macro for each value of the variable; 165 | * here we formed 19 macros; 166 | proc sql noprint; 167 | select name into: mvar1 - :mvar19 168 | from sashelp.class; 169 | quit; 170 | %put &mvar1; 171 | %put &mvar7; 172 | %put &mvar12; 173 | %put &mvar17; 174 | 175 | 176 | 177 | * Debugging options; 178 | * macro debubbing options are global options; 179 | * mprint will print the procedures and datasets inside the macro substituting the value 180 | of any defined macro variable, the final program without macro ; 181 | * mprint output starts with thus: MPRINT(name of macro) : each statement of the final program ; 182 | * noprint deactivates the mprint options; 183 | 184 | options mprint; 185 | %printme; 186 | %printed(dtname=sashelp.class); 187 | 188 | 189 | * serror and merror options are the default; 190 | * serror give warning for non-existing macro variable; 191 | * merror gives warning for non-existing macro catalog or function; 192 | * the noserror and nomerror options deactivates them; 193 | 194 | options serror merror; 195 | %put &pander; * serror will give warning message; 196 | %donnett; * merror will give warning message; 197 | 198 | * mlogic and symbolgen gives different message of the tracing done by macro processor 199 | * the two explains what is happend behide the hoard (tracing of the macro processor exection); 200 | * mlogic has Beginning execution and Ending execution messages, and other messages in between; 201 | * in between messages are: 1. values of parameters at invocation 202 | 2. whether if the %if condition is true or false 203 | 204 | options mlogic symbolgen; 205 | %printed(dtname=sashelp.class); 206 | 207 | 208 | %macro goschool(dta=,mydata=); 209 | proc print data=&dta; 210 | run; 211 | 212 | data &mydata; 213 | set &dta; 214 | length newgender $ 6; 215 | %if sex='M' %then newgender = "Male"; 216 | %else %if sex="F" %then newgender = "Female"; 217 | run; 218 | 219 | proc print data=&mydata; run; 220 | %mend; 221 | 222 | %goschool(dta=sashelp.class, mydata=one) 223 | 224 | 225 | 226 | * Storing and saving macros; 227 | * options sasmstore= links the the folder, and mstored is the save command; 228 | libname mastore "C:\Users\Jose\Documents\SasClinical\macros\mstore"; 229 | options sasmstore=mastore mstored; 230 | 231 | %macro printtf/ store source; 232 | proc print data=sashelp.class; 233 | run; 234 | %mend; 235 | 236 | 237 | * Using saved macros; 238 | * the sasautos options will run the library where the macro is stored; 239 | libname run "C:\Users\Jose\Documents\SasClinical\macros\mstore"; 240 | options sasautos = mstorage; 241 | %printtf; 242 | 243 | 244 | * Autocall macros: use to execute programs save in another file; 245 | * using %include ; 246 | %include "C:\Users\Jose\Documents\SasClinical\macros"; 247 | %include "C:\Users\Jose\Documents\SasClinical\macros\logg.txt"; 248 | 249 | 250 | filename mydoc "C:\Users\Jose\Documents\SasClinical\macros"; 251 | %include mydoc; 252 | 253 | 254 | 255 | * System defined automatic macro variables; 256 | %put _automatic_; 257 | %put &sysdate; 258 | %put &sysver; 259 | %put &syslast; 260 | %put &sysvlong; 261 | %put &sysuserid; 262 | 263 | 264 | * Multiply &; 265 | %let dsn=abc; 266 | %let i = 1; 267 | %let dsn1=abc1; 268 | %let abc1=cba1; 269 | 270 | %put &dsn&i; * ==> abc1 ; 271 | %put &&dsn&i; * ==> abc1 ; * && resolves to &; 272 | 273 | %put &&&dsn&i; * ==> cba1 ; 274 | * first leftmost && resolves to &, then &dsn1 ==> abc, and &i ==> 1; 275 | * now we have &abc1 ==> cba1 ; 276 | 277 | 278 | -------------------------------------------------------------------------------- /procTab.sas: -------------------------------------------------------------------------------- 1 | options nodate nonumber; 2 | 3 | proc tabulate data=sasuser.empdata order=freq format=comma10.; 4 | class hiredate; 5 | var salary; 6 | table hiredate, salary*(n (sum mean)*f=dollar10.2); 7 | format hiredate monname.; 8 | label hiredate="Month Hired"; 9 | title "Total Salary for Staff by Hire Month"; 10 | run; 11 | 12 | 13 | 14 | proc tabulate data=sashelp.cars; 15 | class make drivetrain origin; 16 | var invoice; 17 | table origin="", drivetrain="Drive Train"*invoice=""* 18 | (min="Lowest Price" mean="Average Price")*format=dollar12.2/ rts=23 ; 19 | title; 20 | run; 21 | 22 | 23 | 24 | proc tabulate data=sashelp.cars; 25 | class drivetrain origin cylinders; 26 | var invoice; 27 | table origin*cylinders, drivetrain="Drive Train"*invoice=""*mean=""*format=dollar12.2/ rts=25 ; 28 | title; 29 | run; 30 | 31 | 32 | 33 | proc tabulate data=sashelp.class; 34 | class sex; 35 | var age; 36 | table sex age; 37 | run; 38 | 39 | 40 | proc tabulate data=sasuser.blood; 41 | class gender bloodgrp; 42 | var rbc; 43 | table gender rbc bloodgrp; 44 | run; 45 | 46 | 47 | * Cross tabulation; 48 | * using * , gives flat orientation ; 49 | proc tabulate data=sasuser.blood; 50 | class gender bloodgrp; 51 | var rbc; 52 | table gender*bloodgrp; 53 | run; 54 | 55 | 56 | * using comma (,) give tabular orientation with rows and columns; 57 | * The row before comma and columns after comma ; 58 | proc tabulate data=sasuser.blood; 59 | class gender bloodgrp; 60 | var rbc; 61 | table gender, bloodgrp; 62 | run; 63 | 64 | 65 | * Adding format to manage variable length ; 66 | proc tabulate data=sasuser.blood; 67 | class gender bloodgrp; 68 | var rbc; 69 | table gender, bloodgrp (rbc chole)*(mean*f=7.2 n*f=3.); 70 | run; 71 | 72 | 73 | * multiple cross multiplication ; 74 | * Here gender and bloodgrp forms the row while rbc and chole the columns; 75 | proc tabulate data=sasuser.blood; 76 | class gender bloodgrp; 77 | var rbc; 78 | table gender*bloodgrp, (rbc chole)*(mean*f=7.2 n*f=5.2); 79 | run; 80 | 81 | 82 | * label variables using keylabel ; 83 | proc tabulate data=sasuser.blood; 84 | class gender bloodgrp; 85 | var rbc; 86 | table gender all*bloodgrp all, (rbc chole)*(mean*f=7.2 n*f=5.2); 87 | keylabel mean="Average" all="Total"; 88 | run; 89 | 90 | 91 | * Handle box with rts= and box= ; 92 | * rts to size the length of the box, while box= to insert label or text ; 93 | proc tabulate data=sasuser.blood; 94 | class gender bloodgrp; 95 | var rbc; 96 | table gender*bloodgrp, (rbc chole)*(mean*f=7.2 n*f=5.2) / rts=30 box="Insert text here"; 97 | run; 98 | 99 | -------------------------------------------------------------------------------- /proc_datasets.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical"; 2 | libname newdb "C:\Users\Jose\Documents\SasClinical\Newdata"; 3 | 4 | proc datasets; 5 | quit; 6 | run; 7 | 8 | proc datasets lib=home; 9 | quit; 10 | run; 11 | 12 | proc contents data=home._all_ nods; 13 | run; 14 | 15 | 16 | 17 | * Getting details of datasets; 18 | proc datasets lib=home; 19 | contents data=_all_; 20 | quit; 21 | run; 22 | 23 | proc contents data=_all_; 24 | run; 25 | 26 | 27 | 28 | * Coping dataset; 29 | proc copy in=mylib out=newdb; 30 | run; 31 | 32 | proc datasets nolist; 33 | copy in=mylib out=newdb; 34 | run; 35 | 36 | 37 | 38 | * Selecting datasets ; 39 | proc copy in=mylib out=newdb; 40 | select bmi height final; 41 | run; 42 | 43 | proc datasets nolist; 44 | copy in=mylib out=newdb; 45 | select bmi height final; 46 | quit; 47 | run; 48 | 49 | 50 | * Deleting or save/delete datasets; 51 | proc datasets lib=newdb nolist; 52 | delete bmi height; 53 | quit; 54 | run; 55 | 56 | proc datasets lib=newdb nolist kill; 57 | quit; 58 | run; 59 | 60 | proc datasets lib=newdb nolist; 61 | save final; *delete all except final; 62 | quit; 63 | run; 64 | 65 | 66 | * Modifying datasets; 67 | * 1. label dataset; 68 | * Using data step; 69 | data newdb.bmi(label="Body Mass Index"); 70 | set newdb.bmi; 71 | run; 72 | 73 | 74 | * Using proc datasets, which is faster and more efficient; 75 | proc datasets lib=newdb nolist; 76 | modify height(label="Height of Students"); 77 | quit; 78 | run; 79 | 80 | 81 | * 2. label variables; 82 | * using data step; 83 | data newdb.bmi; 84 | set newdb.bmi; 85 | label height="Heights of Students" 86 | weight="Weights of Students"; 87 | run; 88 | 89 | * using proc datasets which is faster and more efficient; 90 | proc datasets lib=newdb nolist; 91 | modify bmi; 92 | label height="Heights in cm" 93 | weight="Weights in pounds"; 94 | quit; 95 | run; 96 | 97 | 98 | * 3. rename variables and apply formats/informats; 99 | * using data step; 100 | data newdb.visit; 101 | set newdb.visit(rename=(inv=site pat=subj)); 102 | format todate fromdate mmddyy10.; 103 | informat vstdate todate fromdate mmddyy10.; 104 | run; 105 | 106 | 107 | proc datasets lib=newdb nolist; 108 | modify visit; 109 | rename inv=site pat=subj; 110 | format todate fromdate mmddyy10.; 111 | informat vstdate todate fromdate mmddyy10.; 112 | quit; 113 | run; 114 | 115 | -------------------------------------------------------------------------------- /put.sas: -------------------------------------------------------------------------------- 1 | filename myfile "C:\Users\Jose\Documents/myfolders/tab.txt"; 2 | filename myfile2 "C:\Users\Jose\/myfolders/putinfile.txt"; 3 | 4 | data usingput; 5 | set sashelp.class; 6 | file myfile; 7 | if age le 11 then 8 | do; 9 | put name "09"x "Hello" "09"x height "09"x sex; 10 | put 'Hello' '09'x 'hello'; 11 | put 50*"_" 10*"&" 10*"%" 10*"#"; 12 | put #3 @50 name weight; 13 | put name 1-10; 14 | put (weight height age) (dollar12.2); 15 | put height dollar7.2 "09"x age 4.1; 16 | put _infile_; 17 | end; 18 | else 19 | do; 20 | count + 1; 21 | put "(" count 2.0 ")" @; 22 | put +1 name " is of height " height " inches"; 23 | end; 24 | run; 25 | 26 | 27 | 28 | data putinfile; 29 | input name $ age sex $; 30 | file myfile2; 31 | put _infile_; 32 | put @age name; 33 | put @(2*age) name; 34 | put @(2*age) name / 35 | @5 "gender " sex; 36 | put @1 name overprint @1'#######'; 37 | datalines; 38 | Mark 49 M 39 | Uju 35 F 40 | Kelly 56 M 41 | Keth 24 F 42 | ; 43 | run; 44 | 45 | 46 | options nonumber nodate; 47 | title; 48 | 49 | ods escapechar= "\"; 50 | title 'This is the document with page x of y' 51 | j=r 'Page \{pageof}'; 52 | ods rtf file="/folders/myfolders/Odspage/pageof.rtf"; 53 | proc print data=sashelp.air; 54 | run; 55 | ods rtf close; 56 | 57 | 58 | ods escapechar= '\'; 59 | title 'This is the document with page x of y' 60 | j=r 'Page \{thispage} of \{lastpage}'; 61 | ods pdf file='/folders/myfolders/Odspage/pagespdf1.pdf'; 62 | options nonumber nodate center ls=max; 63 | proc print data=sashelp.air; 64 | run; 65 | ods pdf close; -------------------------------------------------------------------------------- /putlog.sas: -------------------------------------------------------------------------------- 1 | options pageno=1 nodate linesize=80 pagesize=60; 2 | filename outfil "C:Documents/home/putlogg.txt"; 3 | 4 | data ExScores; 5 | infile datalines; 6 | input LastName $ FirstName $ Maths Chemisty Biology; 7 | datalines; 8 | Gaylle Nancy 80 92 27 9 | Martin Micheal 95 91 92 10 | Gomez Sebastine 91 98 . 11 | Koshi Shauan 80 87 . 12 | Vancovar Maurine 98 . 98 13 | Kelly Wishdony 92 85 . 14 | ; 15 | run; 16 | 17 | proc print data=ExScores; 18 | run; 19 | 20 | 21 | 22 | DATA error2; 23 | set ExScores; 24 | length reviewed $ 4; 25 | if Maths le 90 then 26 | do; 27 | file log; 28 | put 'Score is less than 90 ' Maths=; 29 | _error_=1; 30 | error "Maths is less than or equals 90 " LastName= FirstName=; 31 | reviewed = "***"; 32 | file outfil; 33 | put LastName FirstName maths chemistry biology reviewed; 34 | putlog "NOTE: Maths score less than or equals 90 " maths= 5.2; 35 | putlog "WARNING: " LastName FirstName " maths score is less than or equals 90"; 36 | putlog "ERROR: Check log for errors"; 37 | end; 38 | else reviewed = "Good"; 39 | run; 40 | 41 | 42 | proc print data=error2; 43 | run; 44 | -------------------------------------------------------------------------------- /report.sas: -------------------------------------------------------------------------------- 1 | libname myfile "C:\Users\Jose\Documents\SasClinical\sql2"; 2 | 3 | 4 | * simple proc report is same as proc print without obs; 5 | proc report data=sashelp.class; 6 | run; 7 | 8 | 9 | 10 | proc sort data=sashelp.class out=class1; 11 | by sex; 12 | run; 13 | 14 | proc format; 15 | value $gender "F"="Female" "M"="Male"; 16 | run; 17 | 18 | * Using proc report; 19 | * group and order options gives the same result; 20 | * across options create dummy variable for categorical variable; 21 | * noprint options removes the variable from the report; 22 | proc report data=class1 nowd headskip headline split="*"; 23 | column ('--' name sex age height weight,('-- wt stats --' min n mean) BMI comment; 24 | define name/'Employee*Name' ; 25 | define age/spacing=4; 26 | define sex/'Gender' width=7 format=$gender.; 27 | define BMI /computed format=6.2; 28 | compute BMI; 29 | BMI = _c5_ /(_c4_ * 0.0254)**2; 30 | endcomp; 31 | define comment/computed length=14; 32 | if BMI lt 18.50 then 33 | comment="Underweight"; 34 | else if BMI ge 18.50 and BMI le 24.99 then 35 | comment="Normal weight"; 36 | else if BMI ge 25.00 and BMI le 29.99 then 37 | comment="Overweight"; 38 | else if BMI ge 30.00 then 39 | comment="Obese"; 40 | endcomp; 41 | compute before _page_; 42 | line @10 'Ages, Weight and Heights of students'; 43 | line @20 'Class 2018'; 44 | endcomp; 45 | compute after; 46 | line ' '; 47 | line @2 85*'-'; 48 | line @5 'Note: Weight in Kg'; 49 | line @5 'Note: Heights in Inches'; 50 | endcomp; 51 | compute after _page_; 52 | line @10 50*'-' 'PAGE END' 50*'-'; 53 | endcomp; 54 | format _numeric_ 6.2; 55 | run; 56 | 57 | 58 | 59 | * Create another report ; 60 | options nodate nocenter nonumber; title; 61 | proc sql; 62 | create table analysis3 as select r.CTR1N, r.SBJ1N, age_1n, racen, region , 63 | gender, AEVEND1O , AEVSER1C , AEVSEV1C , AEVSMR1C , AEVSTT1O , PT_TXT , 64 | SOC_TXT from myfile.dm as l left join myfile.aev as r on l.sbj1n=r.sbj1n and 65 | l.CTR1N=r.CTR1N order by ctr1n , sbj1n; 66 | quit; 67 | 68 | 69 | 70 | %let keepvar = rcp asr aps aesteddtc AEVSEV1C AEVSMR1C lastrec; 71 | 72 | data finalanaly; 73 | set analysis3b end=eof; 74 | centre="02"||put(ctr1n, z2.); 75 | rcp=put(region, region.)||"/"||centre||"/"||put(sbj1n, z5.); 76 | asr=put(age_1n, 2.)||"/"||put(gender, sex.)||"/"||put(racen, race.); 77 | aps=strip(AEVNAM1A)||'/'||strip(PT_TXT)||"/"||strip(SOC_TXT); 78 | aestdtc=substr(AEVSTT1O, 1, 9); 79 | aeendtc=substr(AEVEND1O, 1, 9); 80 | 81 | if AEVSEV1C=. then 82 | AEVSEV1C=0; 83 | 84 | if AEVSEV1C=0 and AEVSMR1C=. then 85 | AEVSMR1C=2; 86 | 87 | if aestdtc=' ' then 88 | aestdtc='01JAN2010'; 89 | 90 | if aeendtc=' ' then 91 | aeendtc='01JAN2011'; 92 | aesteddtc=strip(aestdtc)||"/"||strip(aeendtc); 93 | 94 | if eof then 95 | lastrec=1; 96 | keep &keepvar; 97 | format SBJ1N z5. region region. gender sex. racen race. AEVSEV1C sev. AEVSMR1C 98 | rel.; 99 | run; 100 | 101 | 102 | %let fitto = C:\Users\Jose\Documents\SasClinical\sql2 ; 103 | 104 | proc printto file="&fitto./report3.txt" log="&fitto./report3_log.txt"; 105 | run; 106 | 107 | options nodate nocenter nonumber; 108 | title; 109 | 110 | 111 | proc report data=finalanaly nowd missing spacing=3 headline headskip split="#"; 112 | column('--' lastrec rcp asr aps aesteddtc AEVSEV1C AEVSMR1C);# 113 | define rcp / "Region/#Center/#Patient" width=16; 114 | define asr / 'Age/#Sex/#Race'; 115 | define aps / 'Adverse Event#(Reported/Preferred/System#Organ Class)' flow 116 | order order=internal width=27; 117 | define aesteddtc / 'Start date/#End date' width=20; 118 | define AEVSEV1C / 'Severity'; 119 | define AEVSMR1C / 'Relation#to#Study Drug' center; 120 | define lastrec / display noprint order order=internal; 121 | compute before _page_; 122 | line @3 'Listing 14.3.2-1.2' @30 123 | 'Serious adverse events during double-blind treatment period by treatment'; 124 | line ' '; 125 | line @3 'Treatment: ABC 300 mg'; 126 | endcomp; 127 | rbreak after / skip; 128 | compute after _page_ / left; 129 | line " "; 130 | line @3 114*'_'; 131 | 132 | if not lastrec then 133 | letter='(Continue on next page pls)'; 134 | else 135 | letter='(End of Report)'; 136 | 137 | line @86 letter $28.; 138 | line " "; 139 | line " "; 140 | endcomp; 141 | compute after; 142 | line @3 118*'-'; 143 | line @3 'Severity: Mild=Mild, Mod=Moderate, Sev=Severe'; 144 | line @3 'Relationship to study drug: Not susp=Not suspected, Susp=Suspected'; 145 | line @3 'Gender:1-male 2-Female'; 146 | endcomp; 147 | run; 148 | 149 | 150 | proc printto; 151 | run; 152 | 153 | 154 | 155 | proc report data=sashelp.cars nowd headline headskip split='*'; 156 | column ('--' origin make type msrp,(mean max)); 157 | define origin / group 'Country of Origin'; 158 | define make / order order=internal "Manufacturer" ; 159 | define msrp / analysis 'Min Sale Retail Price'; 160 | define type / group; 161 | break after make / skip summarize; 162 | compute after make ; 163 | make = "Total"; 164 | origin = " "; 165 | line " "; 166 | endcomp; 167 | run; -------------------------------------------------------------------------------- /revision.sas: -------------------------------------------------------------------------------- 1 | libname clinic "C:Documents/SasClinical"; 2 | filename myfile "C:Documents/SasClinical"; 3 | 4 | data mm; 5 | set sashelp.class; 6 | run; 7 | 8 | proc sort data=mm; by sex; run; 9 | 10 | /* What is the result here */ 11 | data clinic.mm2; 12 | merge clinic.mm2 work.mm; 13 | by sex; 14 | run; 15 | 16 | 17 | data hhh; 18 | do until(prod gt 6); 19 | prod + 1; 20 | end; 21 | run; 22 | 23 | 24 | data class1; 25 | infile myfile('class.csv') dlm="," firstobs=2; 26 | input Name$ Sex$ Age Height Weight; 27 | run; 28 | 29 | data _NULL_; 30 | set sashelp.class; 31 | file myfile('class2.csv') dlm=","; 32 | if _N_ = 1 then 33 | put 'Name,Sex,Age,Height,Weight'; 34 | put Name Sex Age Height Weight; 35 | run; 36 | 37 | 38 | data _null_; 39 | set sasuser.finance; 40 | file myfile('finance.csv') dlm=","; 41 | put 'Social Security Number ' SSN Name 42 | ' totaled ' salary : dollar9. Date date9.; 43 | run; 44 | 45 | 46 | ods csvall file='C:Documents/SasClinical/class3.csv'; 47 | proc print data=sashelp.class noobs; 48 | run; 49 | ods csvall close; 50 | 51 | 52 | data emply; 53 | infile datalines; 54 | input name$ age; 55 | datalines; 56 | bruce 30 57 | dan 35 58 | dan . 59 | ; 60 | run; 61 | 62 | 63 | 64 | data Sal; 65 | infile datalines; 66 | input name$ salary; 67 | datalines; 68 | bruce 40000 69 | bruce 35000 70 | dan 37000 71 | dan 68000 72 | ; 73 | run; 74 | 75 | 76 | proc sort data=emply; by name;run; 77 | proc sort data=sal; by name;run; 78 | 79 | 80 | /* How many dataset */ 81 | /* How many observation in dataset mer */ 82 | data mer; 83 | merge emply(in=inem) sal(in=insal); 84 | by name; 85 | if inem and insal; 86 | run; 87 | 88 | 89 | /* How many observation in dataset settt2 */ 90 | data settt2; 91 | set emply(in=inem) sal(in=insal); 92 | by name; 93 | run; 94 | 95 | 96 | /* How many observation in dataset settt3 */ 97 | data settt3; 98 | set emply(in=inem) sal(in=insal); 99 | by name; 100 | run; 101 | 102 | 103 | /* How many observation in dataset settt4 */ 104 | data settt4; 105 | set emply(in=inem) sal(in=insal); 106 | by name; 107 | if inem and insal; 108 | run; 109 | 110 | 111 | /* Why did the program fail */ 112 | proc sort data=emply; by descending name; 113 | proc sort data=sal; by descending name; 114 | data mer2; 115 | merge emply(in=inem) sal(in=insal); 116 | by name; 117 | run; 118 | 119 | 120 | data mndt; 121 | dattt = mdy(03,12,2013); 122 | run; 123 | 124 | 125 | proc format; 126 | value monthfmt 1="January" 2="February" 3="March" 4="April" 127 | 5="May" 6="June" 7="July" 8="August" 128 | 9="September" 10="October" 11="November" 12="December" 129 | ; 130 | run; 131 | 132 | data anniversary(drop=yr tmonth retire) serviceyears (drop=yr tmonth); 133 | set sasuser.mechanics(keep=id lastname firstname hired birth); 134 | Yr= intck('year',hired, today()); 135 | retire = intnx('month',birth,65*12,'end'); 136 | tmonth = month(today()); 137 | MonthEmployed = month(hired); 138 | YearsInService = put(yr,2.)|| " Years in Service"; 139 | Retirement = 'Retirement is on '||put(retire,date9.); 140 | dayto = mdy(01,23,2018); 141 | if Yr gt 20 and month(hired)=tmonth then output anniversary; 142 | output serviceyears; 143 | format YearsInService $35. MonthEmployed monthfmt. dayto date9.; 144 | run; 145 | 146 | 147 | /* What is the outcome here */ 148 | data _null_; 149 | set sashelp.class; 150 | file myfile(class3.csv); 151 | put Name $15. @5 Age weight Height; 152 | run; 153 | 154 | 155 | /* How many dataset */ 156 | data newdata; 157 | infile myfile(class.csv) dlm="," firstobs=2; 158 | input Name $ Sex $ Age Weight Height; 159 | file myfile(class3.csv); 160 | put Name $15. Sex$ Age weight Height; 161 | run; 162 | 163 | 164 | 165 | data substr1; 166 | length Name $ 8; 167 | Name = "john"; 168 | put Name; 169 | i = length(Name); 170 | substr(Name,5,4) = "More"; 171 | put Name; 172 | run; 173 | 174 | 175 | data new; 176 | sample_str = "Pin Code 411014"; 177 | SUBSTR(sample_str, 4, 5) = ":"; 178 | run; 179 | 180 | /* What's the value of totap */ 181 | /* missing operations */ 182 | data psa; 183 | if origp = . then origp = 100; 184 | put origp; 185 | transp = 100; 186 | origp = .; 187 | totap = transp + origp; 188 | totap2 = sum(transp,origp); 189 | run; 190 | 191 | 192 | /* why the retain here */ 193 | /* what is the value of price */ 194 | /* what is the value of costage */ 195 | data grand; 196 | set sashelp.class; 197 | retain grandt 0; 198 | grandt = sum(grandt, age); 199 | total + age; 200 | cost = "20000"; 201 | numb = age; 202 | ddd = "_"; 203 | price = 0.01 * cost; 204 | costage = cost||"_"||age; 205 | cotl = length(costage); 206 | run; 207 | 208 | 209 | /* the length and types of date1-date4 */ 210 | data datem; 211 | date1 = input('13mar2018',date9.); 212 | date2 = put('13mar2018'd,date9.); 213 | date3 = input('13/03/2018',ddmmyy10.); 214 | date4 = put('13mar2018'd,ddmmyy10.); 215 | run; 216 | 217 | 218 | /* How many observation here: */ 219 | /* what is the value of year, month and x */ 220 | data yyy; 221 | do year = 1 to 5; 222 | do month = 1 to 12; 223 | x + 1; 224 | end; 225 | end; 226 | run; 227 | 228 | 229 | /* How many observation here: */ 230 | data yyy2; 231 | do year = 1 to 5; 232 | do month = 1 to 12; 233 | x + 1; 234 | output; 235 | end; 236 | end; 237 | run; 238 | 239 | 240 | 241 | /* what is the value of n */ 242 | data nnn; 243 | do while(n gt 6); 244 | n + 1; 245 | end; 246 | run; 247 | 248 | 249 | /* what is the value of n */ 250 | data nnn; 251 | do while(n lt 6); 252 | n + 1; 253 | end; 254 | run; 255 | 256 | data doy; 257 | set sashelp.class; 258 | run; 259 | 260 | 261 | /* How many variable and observations here */ 262 | data doyear; 263 | do year = 1 to 3; 264 | set sashelp.class; 265 | capital + 5000; 266 | end; 267 | run; 268 | 269 | 270 | /* How many variable and observations here */ 271 | data doyear2; 272 | do year = 1 to 3; 273 | set sashelp.class(obs=3); 274 | capital + 5000; 275 | end; 276 | run; 277 | 278 | /* How many variable and observations here */ 279 | data doyear3; 280 | do year = 1 to 3; 281 | set sashelp.class(obs=3); 282 | capital + 5000; 283 | output; 284 | end; 285 | run; 286 | 287 | /* How many variable and observations here */ 288 | data doyear4; 289 | do year = 1 to 3; 290 | set sashelp.class; 291 | capital + 5000; 292 | output; 293 | end; 294 | run; 295 | 296 | data fil33; 297 | infile datalines; 298 | input name$ 1-4 @; 299 | if name = "Sue" then input age 7-8; 300 | else input indum 10-11; 301 | datalines; 302 | Ruth 39 11 303 | Jose 32 22 304 | Sue 30 33 305 | John 40 44 306 | ; 307 | run; 308 | 309 | 310 | 311 | 312 | data fil31; 313 | infile datalines; 314 | input name$ 1-4 @; 315 | if name = "Sue" then input age 7-8; 316 | else input indum 10-11; 317 | datalines; 318 | Ruth 39 11 319 | Jose 32 22 320 | Sue 30 33 321 | John 40 44 322 | ; 323 | run; 324 | 325 | 326 | 327 | /* what is the value of age when name is Sue */ 328 | data fil33; 329 | infile datalines; 330 | input name$ 1-4 @; 331 | if name = "Sue" then input age 7-8; 332 | else input indum 10-11; 333 | datalines; 334 | Ruth 39 11 335 | Jose 32 22 336 | Sue 30 33 337 | John 40 44 338 | ; 339 | run; 340 | 341 | 342 | data fil33; 343 | infile datalines; 344 | input name$ idnum age; 345 | if age=. then agegrp = "Unknown"; 346 | else if age=1 then agegrp = "Low"; 347 | else if age=2 or 3 then agegrp = "Medium"; 348 | else agegrp = "High"; 349 | datalines; 350 | Ruth 39 1 351 | Jose 32 2 352 | Suew 30 3 353 | Johny 40 . 354 | Sue 30 3 355 | John 40 4 356 | ; 357 | run; 358 | 359 | 360 | data fil55; 361 | infile datalines; 362 | input name idnum age; 363 | if age=. then agegrp = "Unknown"; 364 | else if age=1 then agegrp = "Low"; 365 | else if age=2 or 3 then agegrp = "Medium"; 366 | else agegrp = "High"; 367 | if _error_ then message = "Problem "; 368 | else message = "No Problem"; 369 | datalines; 370 | Ruth 39 1 371 | Jose 32 2 372 | Suew 30 3 373 | Johny 40 . 374 | Sue 30 3 375 | John 40 4 376 | ; 377 | run; 378 | 379 | 380 | /* What is the value of weight, Weight2 */ 381 | data weight2; 382 | infile datalines; 383 | input @1 Age 2. @4 weight 2 @4 Weight2 5; 384 | datalines; 385 | 73 94 386 | ; 387 | run; 388 | 389 | 390 | /* what is the value of agent2 in observation */ 391 | /* there is no value, only one observation is read */ 392 | data agents; 393 | infile datalines dlm=","; 394 | input agent1 $ agent2 $ agent3 $; 395 | datalines; 396 | Bronwm,,Snimitt,Peter,Matthew 397 | ; 398 | run; 399 | 400 | 401 | data agents2; 402 | infile datalines dlm=","; 403 | input agent1 $ price dollar8.; 404 | datalines; 405 | Bronwm,$21,987 406 | Snimitt,$677,845 407 | Peter,$809,874 408 | Matthew,$984,593 409 | ; 410 | run; 411 | 412 | proc sort data=sashelp.class out=classT; 413 | by sex descending weight; 414 | run; 415 | 416 | data filast; 417 | set classT; 418 | by sex descending weight; 419 | retain temp; 420 | if first.sex then do; 421 | temp = weight; 422 | output; 423 | end; 424 | else if last.sex then do; 425 | range = temp - weight; 426 | output; 427 | end; 428 | run; 429 | 430 | 431 | /* What is message when amount is lt 30000 */ 432 | data edut; 433 | infile datalines; 434 | input name$ amount; 435 | if amount ge 30000 then message = "Over 30"; 436 | else if amount lt 30000 then message ="Under 30"; 437 | datalines; 438 | Ruth 29000 439 | Jose 32000 440 | Suew 20999 441 | Johny 40000 442 | Sue 22000 443 | John 49840 444 | ; 445 | run; 446 | 447 | proc print; 448 | run; 449 | 450 | 451 | data r23; 452 | input year qrt budget; 453 | cards; 454 | 2001 3 500 455 | 2001 4 400 456 | 2002 1 700 457 | ; 458 | run; 459 | 460 | data r24; 461 | input year qrt sales; 462 | cards; 463 | 2001 4 300 464 | 2002 1 600 465 | 2002 1 800 466 | 2004 1 900 467 | ; 468 | run; 469 | 470 | proc sql; 471 | select r23.*, sales 472 | from r23, r24; 473 | quit; 474 | 475 | 476 | proc sql; 477 | select sales, r23.* 478 | from r23, r24 479 | where r23.year=r24.year; 480 | quit; 481 | 482 | 483 | %let value1 = 9; 484 | %let value2 = 5; 485 | %let value3 = 5.98; 486 | %let value4 = 98.98; 487 | %put %eval(&value1/&value2); 488 | %put %sysevalf(&value3+&value4); 489 | 490 | data _NULL_; 491 | set edut; 492 | call symput(name, put(amount,dollar.)); 493 | run; 494 | 495 | %put _user_; 496 | 497 | 498 | %put &Ruth &Jose &Suew &Johny &Sue &John; 499 | 500 | proc sql; 501 | select * 502 | from r23 outer union corr 503 | select * from r24; 504 | quit; 505 | 506 | %put &syserr; 507 | 508 | -------------------------------------------------------------------------------- /select.sas: -------------------------------------------------------------------------------- 1 | * Select is used when dealing with long series of mutually exclusive 2 | * condition instead of IF ... THEN ... Else IF ... statement; 3 | data slect; 4 | set sashelp.class; 5 | select(agegrp); 6 | when("child") allowance]=1500; 7 | when("Adult") 8 | do; 9 | if gender="F" then allowance=1200; 10 | else if gender "M" then allowance=1000; 11 | end; 12 | when("Senior") allowance=1250; 13 | otherwise; 14 | end; 15 | run; 16 | 17 | 18 | * without select expression; 19 | data snoexp; 20 | set sashelp.class; 21 | select; 22 | when (gender="F") benefit=1200; 23 | when (gender="M") benefit=1000; 24 | otherwise; 25 | end; 26 | run; -------------------------------------------------------------------------------- /sortLin.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical"; 2 | 3 | * Sorting using sortseq=linguistic options, strength=position; 4 | * this sort data without regard to variable case; 5 | proc sort data=home.team out=home.sortedTeam 6 | sortseq=linguistic(strength=primary); 7 | by Country position; 8 | run; 9 | 10 | proc print data=home.sortedTeam; 11 | by country position; 12 | id country position; 13 | title "World Cup Teams"; 14 | title2 "Sorted using sortseq linguistic option"; 15 | run; 16 | 17 | * Display the linguistic information using proc contents; 18 | * so that other program will have access to the linguistic collation; 19 | proc contents data=home.sortedTeam; 20 | run; 21 | 22 | 23 | * Sorting using sortseq=linguistic options, alternate_handling=shifted; 24 | * this sort data without regard to variable with extra blank, punctuations 25 | or other characters; 26 | proc sort data=home.extraX out=home.sortedExtra 27 | sortseq=linguistic(alternate_handling=shifted); 28 | by fullname; 29 | run; 30 | 31 | 32 | proc print data=home.sortedExtra; 33 | by fullname; 34 | id fullname; 35 | run; 36 | 37 | 38 | proc contents data=home.sortedExtra; 39 | run; 40 | 41 | 42 | * Sorting using sortseq=linguistic options, numeric_collation=on; 43 | * this sort data by order of the integer within a text; 44 | * 30th street, before 32nd street; 45 | proc sort data=home.address out=home.address2 46 | sortseq=linguistic(numeric_collation=on); 47 | by street; 48 | run; 49 | 50 | proc print data=home.address2; 51 | by street; 52 | id street zip; 53 | run; 54 | 55 | 56 | proc contents data=home.address2; 57 | run; -------------------------------------------------------------------------------- /sql.sas: -------------------------------------------------------------------------------- 1 | options firstobs=1 obs=1 pageno=1 ls=180 ps=100; 2 | libname home "C:\Users\Jose\Documents\SasClinical"; 3 | 4 | 5 | /* Creating SQL Queries */ 6 | proc sql; 7 | select Subjid, Siteid, Gender, Age 8 | from home.double 9 | where Age < 40 10 | group by Gender 11 | Order by Age; 12 | quit; 13 | 14 | 15 | /* Querying multiple tables */ 16 | proc sql; 17 | select double.Subjid, Studyid, Gender, Txt, Dose 18 | from home.double, home.treatment 19 | where double.Subjid = treatment.Subjid 20 | order by Txt; 21 | quit; 22 | 23 | 24 | /* Summarizing table data : 25 | AVG, MEAN = Average or mean of values 26 | COUNT, FREQ, N = Aggregate number of non-missing values 27 | CSS = Corrected sum of squares 28 | CV = Coefficient of variation 29 | MAX = Largest value 30 | MIN = Smallest value 31 | NMISS = Number of missing values 32 | PRT = Probability of a greater absolute value of Student's t 33 | RANGE = Difference between the largest and smallest values 34 | STD = Standard deviation 35 | STDERR = Standard error of the mean 36 | SUM = Sum of values 37 | SUMWGT = Sum of the weight variable values, which is 1 38 | T = Testing the hypothesis that the population mean is zero 39 | USS = Uncorrected sum of squares 40 | VAR = variance 41 | */ 42 | proc sql; 43 | select Dose, count(Dose) as NumberTxt 44 | from home.treatment 45 | group by Dose; 46 | quit; 47 | 48 | 49 | /* Creating table to store query results*/ 50 | proc sql; 51 | create table home.summary as 52 | select Siteid, Gender, avg(Age) as AverageAge 53 | from home.double 54 | group by Siteid Gender; 55 | quit; 56 | 57 | 58 | proc format; 59 | value range 40000-high ='High' 60 | 26000 -< 40000 ='Medium' 61 | other = 'Low'; 62 | run; 63 | 64 | 65 | proc sql; 66 | select model, make, msrp, 67 | put(msrp, range.) as range 'Price Range' 68 | from sashelp.cars 69 | where calculated range in ('High', 'Medium'); 70 | quit; 71 | 72 | 73 | proc sql; 74 | select model, make, msrp, 75 | msrp as range 'Price Range' 76 | from sashelp.cars 77 | where put(msrp, range.) in ('High', 'Medium'); 78 | quit; 79 | 80 | 81 | 82 | 83 | 84 | proc sql; 85 | select type, origin, mean(msrp) as meanp "Mean Price" format = dollar12. 86 | from sashelp.cars 87 | group by type, origin 88 | order by type desc, meanp desc; 89 | quit; 90 | 91 | -------------------------------------------------------------------------------- /sql2.sas: -------------------------------------------------------------------------------- 1 | libname home "C:\Users\Jose\Documents\SasClinical\sql2"; 2 | 3 | 4 | * Create table with variable names and attributes; 5 | proc sql; 6 | create table sqlTable1 (name char(10), age num, gender char); 7 | quit; 8 | 9 | 10 | * fill table with with values; 11 | proc sql; 12 | insert into sqlTable1 13 | values('Mary', 56, 'F') 14 | values('John', 67, 'M') 15 | values('Anna', 43, 'F') 16 | ; 17 | quit; 18 | 19 | 20 | * Using set statement to insert values; 21 | * Here, the order don't matter; 22 | proc sql; 23 | insert into sqlTable1 24 | set name='Kelly', age=51, gender='M' 25 | set gender='F', name='Jane', age=39 26 | ; 27 | quit; 28 | 29 | 30 | * Print using select statement; 31 | proc sql; 32 | select * from sqlTable1; 33 | quit; 34 | 35 | proc sql; 36 | select name, gender from sqlTable1; 37 | quit; 38 | 39 | 40 | * sorting the data; 41 | proc sql; 42 | create table sqlTable2 as 43 | select * from sqlTable1 44 | order by gender desc, age ; 45 | quit; 46 | 47 | 48 | * sort by position of variable; 49 | proc sql; 50 | create table sqlTable3 as 51 | select * from sashelp.class 52 | order by 2, age desc; 53 | quit; 54 | 55 | 56 | * create format; 57 | proc format libray=library; 58 | value $genderfmt2 59 | "F"="Female" 60 | "M"="Male"; 61 | run; 62 | 63 | 64 | * Apply formats and rename variables; 65 | proc sql; 66 | create table sqlTable4 as 67 | select name as SubName 'Student Name', 68 | age as Age, 69 | sex as Gender foramt=$genderfmt2., 70 | Height as Height_cm 'Height in cm', 71 | Weight as Weight_kg 'Weight in Kg' 72 | from sashelp.class; 73 | quit; 74 | 75 | 76 | proc sql; 77 | create table sqlTable4 as 78 | select name as SubName 'Student Name', 79 | age as Age, 80 | sex as Gender foramt=$genderfmt2., 81 | Height as Height_cm 'Height in cm', 82 | Weight as Weight_kg 'Weight in Kg' 83 | from sashelp.class 84 | where Gender="F"; 85 | quit; 86 | 87 | 88 | * create new variable; 89 | proc sql; 90 | create table sqlTable5 as 91 | select name as SubName 'Student Name', 92 | age as Age, 93 | sex as Gender foramt=$genderfmt2., 94 | Height as Height_cm 'Height in cm', 95 | Weight as Weight_kg 'Weight in Kg', 96 | age+12 as AgePlus, 97 | case when age <= 20 then 'Teenager' 98 | when age > 20 and age <= 30 then 'Young' 99 | when age > 30 and age <= 40 then 'Middle Age' 100 | else 'Older' end as AgeGrp 101 | from sashelp.class 102 | where Gender="F"; 103 | quit; 104 | 105 | 106 | * Using newly created variables, calculated keyword; 107 | * calculated keyword allows you to directly used newly created variable ; 108 | proc sql; 109 | select * , (weight**2) as weightSq, Height/ calculated weightSq as Bmi 110 | from sashelp.class; 111 | quit; 112 | 113 | proc sql; 114 | select * , (height*0.0254)**2 as Heightsq, 115 | weight/calculated Heightsq as Bmi 116 | from sashelp.class; 117 | quit; 118 | 119 | 120 | * using distinct function; 121 | proc sql; 122 | select distinct(age) from sashelp.class; 123 | quit; 124 | 125 | 126 | proc sql; 127 | select count(distinct age) as Agedist, count(distinct sex) as SexCat 128 | from sashelp.class; 129 | quit; 130 | 131 | * This select distinct combination of age and sex ; 132 | proc sql; 133 | select distinct age,sex 134 | from sashelp.class; 135 | quit; 136 | 137 | 138 | * describe and delete table (using drop); 139 | proc sql; 140 | describe table sqlTable5; 141 | quit; 142 | 143 | 144 | * This will delete the table ; 145 | proc sql; 146 | drop table sqlTable5; 147 | quit; 148 | 149 | 150 | * Using sas functions ; 151 | proc sql; 152 | select Weight, ceil(Weight) as Weight2, Height, 153 | floor(Height) as Height2, ceil(Height) as HeightC 154 | from sashelp.class; 155 | quit; 156 | 157 | 158 | * generating statistics; 159 | proc sql; 160 | select sex, count(age) as n, min(age) as MinAge, 161 | mean(Height) as Ave_Height foramt=6.2, mean(Weight) as Ave_Weight format=6.2 162 | from sashelp.class 163 | group by sex; 164 | quit; 165 | 166 | 167 | 168 | 169 | 170 | 171 | * sql set operators; 172 | * Union all, Union, intersect, except; 173 | 174 | * generate test dataset; 175 | data ftable mtable; 176 | set sashelp.class; 177 | if sex='F' then output ftable; 178 | else if sex ='M' then output mtable; 179 | run; 180 | 181 | 182 | * union all combines two tables without sorting; 183 | proc sql; 184 | select * from ftable 185 | union all 186 | select * from mtable 187 | quit; 188 | 189 | 190 | * union combines two tables with sorting; 191 | * sorting using all variables sequentially starting with the first observation; 192 | proc sql; 193 | select * from ftable 194 | union 195 | select * from mtable 196 | quit; 197 | 198 | * Intersect returns common observations matched on selected variable; 199 | * Below no observation was select, observation must match on all variables; 200 | proc sql; 201 | select * from ftable 202 | intersect 203 | select * from mtable; 204 | quit; 205 | 206 | 207 | * Here matched observation(s) on age, Weight and Height is returned; 208 | proc sql; 209 | select age, Weight, Height from ftable 210 | intersect 211 | select age, Weight, Height from mtable; 212 | quit; 213 | 214 | * Except returns non matching observations in table1; 215 | * Here table1 is ftable, so will print non matching observations in ftable ; 216 | proc sql; 217 | select age, Weight from ftable 218 | except 219 | select age, Weight from mtable; 220 | quit; 221 | 222 | 223 | 224 | * feedback and outobs= options; 225 | * feedback option output final transformed code to the log; 226 | * outobs= is used to limit the number of observation in the output; 227 | * and a warning thus -- WARNING: Statement terminated early due to OUTOBS=10 option.; 228 | proc sql feedback outobs=10; 229 | select * from sashelp.class; 230 | quit; 231 | 232 | 233 | * selecting range of observation using monotonic() ; 234 | proc sql feedback; 235 | select * from sashelp.class 236 | where monotonic() between 12 and 18; 237 | quit; 238 | 239 | 240 | 241 | * Alter table; 242 | * can add or drop variable; 243 | proc sql; 244 | alter table ftable add race char(12); 245 | quit; 246 | 247 | proc sql; 248 | alter table ftable drop weight; 249 | quit; 250 | 251 | 252 | * Duplicating or Copying; 253 | proc sql; 254 | create table dup1 as 255 | select *, sex as Gender 256 | from sashelp.class; 257 | quit; 258 | 259 | 260 | proc sql; 261 | create table dup2 as 262 | select * 263 | from sashelp.class; 264 | alter table dup2 add Gender char; 265 | update dup2 set Gender=sex; 266 | quit; 267 | 268 | 269 | 270 | * modify a variable values ; 271 | proc sql; 272 | create table dup3 as 273 | select * 274 | from sashelp.class; 275 | alter table dup3 modify sex char(6); 276 | update dup3 set sex= case when sex="F" then "Female" 277 | else "Male" 278 | end; 279 | quit; 280 | 281 | 282 | * Coalesce function to replace missing values; 283 | proc sql; 284 | create table dup4 as 285 | select coalesce(name, "Unknown") as Name, 286 | coalesce(age,0) as Age,coalesce(gender,"unk") as Gender 287 | from table2; 288 | quit; 289 | 290 | 291 | * Joins; 292 | * simple, inner, outer(left, right, full); 293 | * Natural, self, Cross , Union; 294 | 295 | * Simple Join, using where statement to combine multiple tables; 296 | proc sql; 297 | select * from ftable, mtable 298 | where ftable.weight=mtable.weight; 299 | quit; 300 | 301 | 302 | * Inner joins for only two tables; 303 | proc sql; 304 | select * from ftable inner join mtable 305 | on ftable.weight=mtable.weight; 306 | quit; 307 | 308 | 309 | * Outer Joins; 310 | * left outer join, take all from the leftmost table and add matches to the right table; 311 | proc sql; 312 | select * from ftable left join mtable 313 | on ftable.weight=mtable.weight; 314 | quit; 315 | 316 | * Right outer join, take all from the rightmost table and add matches to the left table; 317 | proc sql; 318 | select * from ftable right join mtable 319 | on ftable.weight=mtable.weight; 320 | quit; 321 | 322 | 323 | 324 | * Natural join, makes join using variables common to both tables; 325 | * rename sex in ftable; 326 | proc sql; 327 | create table ftable2 as 328 | select name as Fname, sex as Gender, Weight, Height 329 | from ftable; 330 | quit; 331 | 332 | proc sql; 333 | select * from ftable2 natural join mtable; 334 | quit; 335 | 336 | 337 | * Self join; 338 | * uses where to subset the dataset; 339 | proc sql; 340 | select * from ftable 341 | where age ge 35; 342 | quit; 343 | 344 | 345 | * Cross join make a cross joint, attached each observation left to all observation on the right table; 346 | * Total number of n X m observations, n is number of observations in left table; 347 | * while m is the number of observations in the right table; 348 | proc sql; 349 | select * from ftable cross join mtable 350 | quit; 351 | 352 | 353 | * Union join; 354 | * Stacks the tables; 355 | proc sql; 356 | select * from ftable union join mtable; 357 | quit; -------------------------------------------------------------------------------- /sql3.sas: -------------------------------------------------------------------------------- 1 | * This demonstrates some sql functions ; 2 | * creating macro variable using into ; 3 | proc sql; 4 | select monotonic() as Obs, name, age 5 | into :name1 - :name19, :age1 - :age19 6 | from sashelp.class; 7 | quit; 8 | 9 | 10 | 11 | * using monotonic() function ; 12 | * This issues a warning message in the log ; 13 | * WARNING: Statement terminated early due to OUTOBS=12 option. ; 14 | * select the first 12 observation with outobs option ; 15 | proc sql outobs=12; 16 | select * from sashelp.class; 17 | quit; 18 | 19 | proc sql; 20 | select monotonic() as Obs, * from sashelp.class; 21 | quit; 22 | 23 | * select the first 12 observation with monotonic function ; 24 | * No warning message here !! ; 25 | proc sql; 26 | select * 27 | from sashelp.class 28 | where monotonic() <= 12; 29 | quit; 30 | 31 | 32 | * This select range of observation ; 33 | proc sql; 34 | select * 35 | from sashelp.class 36 | where monotonic() between 9 and 15; 37 | quit; 38 | 39 | 40 | 41 | * generate data set ; 42 | data demo(drop = i); 43 | do i = 1 to 90; 44 | Age = int(ranuni(89) * 100); 45 | Age2 = ceil(ranuni(456) * 100); 46 | Weight = floor(ranuni(789) * 1000); 47 | SBP = floor(ranuni(12) * 200); 48 | if Age < 16 or Age > 90 then call missing(Age); 49 | if Age2 < 16 or Age2 > 90 then call missing(Age2); 50 | if Weight < 80 or Weight > 220 then call missing(Weight); 51 | output; 52 | end; 53 | run; 54 | 55 | 56 | * Using coalesce function ; 57 | proc sql; 58 | select monotonic() as Obs, *, coalesce(Age, Age2, ceil(avg(Age))) as newAge, 59 | coalesce(weight, floor(avg(weight))) as newWt 60 | from demo; 61 | quit; 62 | 63 | 64 | 65 | * count, nmiss function ; 66 | 67 | proc sql noprint; Create table mmn as 68 | select count(*) as N 'Total', 69 | count(Age) as Age 'Non-missing Age', 70 | nmiss(Age) as Agem 'Missing Age', 71 | count(Age2) as Age2 'Non-missing Age2', 72 | nmiss(Age2) as Age2m 'Missing Age2', 73 | count(Weight) as Weight 'Non-missing Weight', 74 | nmiss(Weight) as Weightm 'Missing Weight' 75 | from demo; 76 | quit; 77 | 78 | * Transpose the data ; 79 | proc transpose data=mmn 80 | name=Variables 81 | label=Variable_Labels 82 | out=TransMMN; 83 | var n age agem age2 age2m weight weightm; 84 | run; 85 | 86 | 87 | 88 | * Create format ; 89 | proc format; 90 | value sbpfmt 91 | 160-high = 'Severe' 92 | 140-<160 = 'Moderate' 93 | 120-<140 = 'Normal' 94 | other = 'Low' 95 | ; 96 | run; 97 | 98 | 99 | proc sql; 100 | select Age, weight, sbp 101 | from demo 102 | where sbp between 80 and 180; 103 | quit; 104 | 105 | 106 | * Using put and format to subset the data 107 | proc sql; 108 | select Age, weight, sbp format=sbpfmt. 109 | from demo 110 | where put(sbp,sbpfmt.) in ("Severe","Moderate"); 111 | quit; 112 | -------------------------------------------------------------------------------- /trailingAT.sas: -------------------------------------------------------------------------------- 1 | /* 2 | Using @@ to read multiple records per line. 3 | 4 | The @@ holds the line for further iterations of the data step. 5 | 6 | */ 7 | 8 | libname home "C:\Users\Jose\Documents\SasClinical"; 9 | 10 | data home.double; 11 | infile datalines; 12 | input Subjid$ Siteid$ Age Gender$ @@; 13 | datalines; 14 | A20sub Inv2118 38 M A21sub Inv2138 46 F A23sub Inv2148 37 F 15 | A22sub Inv2148 39 F A25sub Inv2118 56 M A24sub Inv2148 66 F 16 | A26sub Inv2128 44 F A30sub Inv2128 51 M A28sub Inv2118 56 F 17 | A27sub Inv2148 67 F A29sub Inv2148 70 M A44sub Inv2138 73 F 18 | A34sub Inv2138 45 M A31sub Inv2118 50 F A32sub Inv2128 48 F 19 | A33sub Inv2138 37 F A36sub Inv2128 46 M A35sub Inv2148 77 F 20 | A45sub Inv2138 65 F A38sub Inv2128 39 M A37sub Inv2128 61 M 21 | A40sub Inv2118 76 F A39sub Inv2138 43 M A42sub Inv2118 58 F 22 | ; 23 | run; 24 | 25 | proc print data=home.double; 26 | run; 27 | 28 | data home.treatment; 29 | infile datalines; 30 | input Subjid$ Studyid$ Txt$ Dose$ @@; 31 | datalines; 32 | A20sub Inv2008 Y 1 A21sub Inv2008 N 0 A23sub Inv2008 Y 3 33 | A22sub Inv2008 N 0 A25sub Inv2008 Y 1 A24sub Inv2008 N 0 34 | A26sub Inv2008 Y 2 A30sub Inv2008 Y 3 A28sub Inv2008 Y 2 35 | A27sub Inv2008 Y 2 A29sub Inv2008 N 0 A44sub Inv2008 Y 3 36 | A34sub Inv2008 Y 1 A31sub Inv2008 Y 3 A32sub Inv2008 N 0 37 | A33sub Inv2008 N 0 A36sub Inv2008 Y 2 A35sub Inv2008 N 0 38 | A45sub Inv2008 Y 1 A38sub Inv2008 Y 2 A37sub Inv2008 Y 1 39 | A40sub Inv2008 N 0 A39sub Inv2008 Y 3 A42sub Inv2008 N 0 40 | ; 41 | run; 42 | 43 | proc print data=home.treatment; 44 | run; 45 | 46 | /* 47 | Using single trailing @, to hold the line for another input 48 | 49 | The @ holds the line for multiple iterations within one data step. 50 | 51 | Usally work with Output statement; 52 | 53 | */ 54 | 55 | 56 | data home.single; 57 | infile datalines; 58 | input Name$ Age Gender$ Weight Height @; 59 | if Gender = 'F' then do; 60 | BMI = 1.1*Weight/((Height*0.01)**2); 61 | input TaxR; 62 | Comment = "Female Taxation rule"; 63 | Output; 64 | end; 65 | else if Gender = 'M' then do; 66 | BMI = Weight/((Height*0.01)**2); 67 | input TaxR; 68 | TaxR = TaxR * 1.21; 69 | BMI = Weight/((Height*0.01)**2); 70 | Comment = "Male Taxation rule"; 71 | Output; 72 | end; 73 | format TaxR nlmnlinr14.2; 74 | datalines; 75 | Jones 37 M 74.8 148 2245 76 | Mary 34 F 56.2 138 2232 77 | Jane 45 F 67.8 122 2421 78 | Peter 44 M 73.5 168 2355 79 | John 39 M 70.2 161 2346 80 | Mark 32 M 69.7 159 2156 81 | James 45 M 66.1 163 2145 82 | Helen 38 F 55.0 145 2034 83 | Ann 31 F 59.1 136 2456 84 | ; 85 | run; 86 | 87 | proc print data=home.single; 88 | run; 89 | 90 | 91 | data home.census(drop=code); 92 | retain City State; 93 | input code$ @; 94 | if code='City' then 95 | input City :$10. State$; 96 | else if code='Pol' then 97 | do; 98 | input FirstName$ LastName$ Age; 99 | Output; 100 | end; 101 | datalines; 102 | City Baltimore Maryland 103 | Pol Mark John 38 104 | Pol James Orange 45 105 | Pol Harley Johnson 56 106 | City Houston Texas 107 | Pol Pauline Barker 62 108 | Pol Kinddy Lawson 51 109 | run; 110 | 111 | proc print data=home.census; 112 | run; 113 | 114 | -------------------------------------------------------------------------------- /transpose.sas: -------------------------------------------------------------------------------- 1 | options nodate pageno=1 linesize=120 pagesize=90; 2 | 3 | libname thome "C:\Users\Jose\Documents\SasClinical\proc\tranpose"; 4 | 5 | data thome.prices; 6 | input Product $ Code $ Gprice Discount Fprice; 7 | datalines; 8 | Tv x3487 860 50 810 9 | Radio r7489 560 10 550 10 | Mwave m5892 98 5 93 11 | Pc p8931 1240 40 1200 12 | Mouse j8910 40 3 37 13 | Hphone k9013 56 3 53 14 | Heater h9234 590 50 540 15 | Iron i7569 120 10 110 16 | ; 17 | 18 | 19 | * use transpose function to make the data long; 20 | * You can use options like, prefix, suffix, name; 21 | * Can use statements like, id, idlabel, by (rememeber data must be sorted), var, copy; 22 | * Id statement selects the variable values to use as column names for transposed data; 23 | * Here Values in Product variable are used as column names ie. Tv, Radio, Mwave; 24 | * Transpose function uses COL1 - COL.. if id statement is omitted; 25 | * name is used to represent the column name of the transposed variable i.e Gprice, Discount, Fprice; 26 | proc transpose data=thome.prices 27 | out=thome.tprices 28 | name=SalePrices; 29 | id Product; 30 | run; 31 | 32 | 33 | * Using proc print to see the data ; 34 | * proc transpose don't print output; 35 | proc print data=thome.tprices; 36 | run; 37 | 38 | 39 | * Use var statement to select variable to include in the transposition; 40 | * Transpose function works only on numeric variables if var is omitted; 41 | * If omitted transpose works on all numeric variables; 42 | proc transpose data=thome.prices 43 | out=thome.FFprices 44 | name=SalePrices; 45 | var Fprice; 46 | id Product; 47 | run; 48 | 49 | 50 | * Using proc print to see the data ; 51 | * proc transpose don't print output; 52 | proc print data=thome.tprices; 53 | run; 54 | 55 | 56 | * prefix and suffix options are useful; 57 | * 1. if id statement refers to numeric variable; 58 | * 2. Without Id statement and you want to form specific/insightful column names; 59 | proc transpose data=thome.prices 60 | out=thome.FFprices2 61 | name=PriceClass 62 | prefix=product; 63 | 64 | run; 65 | 66 | * Using proc print to see the data ; 67 | * proc transpose don't print output; 68 | proc print data=thome.FFprices2; 69 | run; 70 | 71 | 72 | * Using by statement in transpose function; 73 | * the dataset must be sorted first; 74 | data thome.studentscore; 75 | input student $ subject $ score; 76 | datalines; 77 | Mark Physics 89 78 | Jane Maths 69 79 | Mark Maths 87 80 | Mark Biology 88 81 | Mark Agric 85 82 | Jane Biology 67 83 | Jane Agric 98 84 | Jane Econs 93 85 | Mary Maths 84 86 | Edward Maths 78 87 | Mary Biology 84 88 | Mary Agric 94 89 | Edward Agric 76 90 | Mary Physics 75 91 | Edward Physics 87 92 | Mark Econs 75 93 | Mary Econs 92 94 | Edward Econs 88 95 | Edward Biology 86 96 | Jane Physics 69 97 | ; 98 | proc sort data=thome.studentscore 99 | out=thome.studentsorted; 100 | by student; 101 | run; 102 | 103 | 104 | * Transpose and drop the _NAME_ variable; 105 | proc transpose data=thome.studentsorted 106 | out=thome.tsort(drop=_name_) ; 107 | id subject; 108 | by student; 109 | run; 110 | 111 | 112 | * Using proc print to see the data ; 113 | * proc transpose don't print output; 114 | proc print data=thome.tsort; 115 | run; 116 | 117 | 118 | 119 | 120 | * Transpose to re-transpose; 121 | proc transpose data=thome.studentsorted 122 | out=thome.tsort2; 123 | id subject; 124 | by student; 125 | run; 126 | 127 | 128 | * Using proc print to see the data ; 129 | * proc transpose don't print output; 130 | proc print data=thome.tsort2; 131 | run; 132 | 133 | 134 | 135 | * This is the dataset ; 136 | data FinalEx; 137 | input Name $ Math Bios Physics Chem Eng Comp Agric; 138 | datalines; 139 | John 85 85 86 85 87 86 87 140 | Jane 80 79 79 78 78 79 78 141 | Peter 78 77 77 77 76 76 77 142 | Patrick 84 84 85 84 83 84 85 143 | Jude 80 81 80 80 79 79 80 144 | Okoye 79 79 79 80 80 78 80 145 | Ruth 83 83 85 85 86 87 87 146 | Benson 81 83 82 82 83 83 82 147 | Huggan 81 81 81 82 82 83 81 148 | Mary 80 81 82 82 82 84 86 149 | Kelly 84 85 84 83 83 83 84 150 | Oneil 74 75 75 76 75 76 76 151 | Mathar 83 84 82 81 83 83 82 152 | vinta 86 87 87 87 87 87 86 153 | Winston 82 83 84 85 84 85 86 154 | ; 155 | run; 156 | 157 | %let sub = Math Bios Physics Chem Eng Comp Agric; 158 | 159 | proc format; 160 | value subfmt 1 = "Mathematics" 2 = "Biology" 3 = "Physics" 161 | 4 = "Chemistry" 5 = "English Language" 162 | 6 = "Computer Science" 7 = "Agricultural Science" 163 | ; 164 | value $submtt "Math" = "Mathematics" 165 | "Bios" = "Biology" 166 | "Physics" = "Physics" 167 | "Chem" = "Chemistry" 168 | "Eng" = "English Language" 169 | "Comp" = "Computer Science" 170 | "Agric" = "Agricultural Science" 171 | ; 172 | run; 173 | 174 | data longEX; 175 | set FinalEx; 176 | array scr{7} ⊂ 177 | array temp{7}$ _temporary_ ("Maths" "Biology" "Physics" "Chem" "EngLng" "CompSC" "AgricSC"); 178 | length ExamNum $ 28; 179 | Student + 1; 180 | 181 | do subject = 1 to 7; 182 | score = scr{subject}; 183 | ExamNum = "2018/Nbexm/B89/"||put(Student,z3.)||"/"||temp(subject); 184 | output; 185 | end; 186 | drop &sub Student; 187 | format subject subfmt.; 188 | run; 189 | 190 | 191 | * using Transpose ; 192 | proc transpose data=finalex out=tfinal 193 | name=Subject; 194 | id name; 195 | format Subject $submtt.; 196 | run; 197 | 198 | proc print data=tfinal; 199 | format Subject $submtt.; 200 | run; 201 | 202 | 203 | * First sort ; 204 | proc sort data=tfinal out=tfinal2; 205 | by subject; 206 | run; 207 | 208 | 209 | * Re-transpose ; 210 | proc transpose data=tfinal out=Rfinal; 211 | id subject; 212 | run; 213 | --------------------------------------------------------------------------------