### SAS FAQ How can I see the number of missing values and patterns of missing values in a data file?

We would like to thank Mike Zdeb of University at Albany School of Public Health who emailed us with his suggestions/examples to improve this page.

Sometimes, a data set may have "holes" in them, i.e., missing values and we may want to know  the number of missing values of all the variables and the distribution of the missing values. We will use the following data set as our example data set.

data test;
input landval improval totval salepric saltoapr city $6. season$8.;
datalines;
30000     64831     94831    118500   1.25  A    spring
30000     50765     80765     93900    .         winter
46651     18573     65224         .   1.16  B
45990     91402         .    184000   1.34  C    winter
42394         .     40575    168000   1.43
.      3351     51102    169000   1.12  D    winter
63596      2182     65778         .   1.26  E    spring
56658     53806     10464    255000   1.21
51428     72451         .         .   1.18  F    spring
93200         .      4321    422000   1.04
76125     78172     54297    290000   1.14  G    winter
.     61934     16294    237000   1.10  H    spring
65376     34458         .    286500   1.43       winter
42400         .     57446         .    .    K
40800     92606     33406    168000   1.26  S
;
run;

#### 1. Number of missing values vs. number of  non missing values in each variable

The first thing we are going to look at the variables that have a lot of missing values. For numerical variables, we use proc means with the options n and nmiss.

proc means data = test n nmiss;
var _numeric_;
run;
VariableNN Misslandval132improval123totval123salepric114saltoapr132

For character variables, we can use proc freq to display the number of missing values in each variable.

proc freq data = test;
tables city season ;
run;
  cityFrequencyPercentCumulativeCumulativeFrequencyPercentA110110B110220C110330D110440E110550F110660G110770H110880K110990S11010100Frequency Missing = 5seasonFrequencyPercentCumulativeCumulativeFrequencyPercentspring444.44444.44winter555.569100Frequency Missing = 6

#### 2. Number of missing values in each observation

We can also look at the number of missing values in each observation. For example, we can use SAS function cmiss to store the number of missing values from both numeric and character variables in each observation.

data test1;
set test;
miss_n = cmiss(of landval -- season);
run;

proc print data = test1;
run;

Obslandvalimprovaltotvalsalepricsaltoaprcityseasonmiss_n13000064831948311185001.25Aspring0230000507658076593900.winter23466511857365224.1.16B244599091402.1840001.34Cwinter1542394.405751680001.4336.3351511021690001.12Dwinter1763596218265778.1.26Espring185665853806104642550001.21295142872451..1.18Fspring21093200.43214220001.043117612578172542972900001.14Gwinter012.61934162942370001.1Hspring1136537634458.2865001.43winter21442400.57446..K4154080092606334061680001.26S1

#### 3. Distribution of missing values

We can also look at the patterns of missing values. By default the MI procedure will output missing data patterns for the variables in the specified datasets. If no var statement is specified Proc MI will output a table for the all the variables in a dataset. The ods select statement tells SAS to only output the "Missing Data Patterns" table.

proc mi data=test;
ods select misspattern;
run;Missing Data PatternsGrouplandvalimprovaltotvalsalepricsaltoaprFreqPercentGroup Meanslandvalimprovaltotvalsalepricsaltoapr1XXXXX426.675089672354482502078751.2152XXXX.16.6730000507658076593900.3XXX.X213.33551241037865501.1.214XX.XX213.335568362930.2352501.3855XX..X16.675142872451..1.186X.XXX213.3367797.224482950001.2357X.X..16.6742400.57446..8.XXXX213.33.32643336982030001.11

You will notice that this report only contains information for numeric variables not character. Another approach to achieve the same output could be via making use of formats, which then allows for character variables to be included. The order of the patterns is different but the information is still the same.

proc format;
value nm . = '.' other = 'X';
value $ch ' ' = '.'other = 'X'; run; proc freq data=test; table landval*improval*totval*salepric*saltoapr*city*season / list missing nocum; format _numeric_ nm. _character_$ch.;
run;landvalimprovaltotvalsalepricsaltoaprcityseasonFrequencyPercent.XXXXXX213.33X.X..X.16.67X.XXX..213.33XX..XXX16.67XX.XX.X16.67XX.XXXX16.67XXX.XX.16.67XXX.XXX16.67XXXX..X16.67XXXXX..16.67XXXXXX.16.67XXXXXXX213.33

The content of this web site should not be construed as an endorsement of any particular web site, book, or software product by the University of California.