<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Juletip #1 - Finding Missing data in SAS Community Nordic</title>
    <link>https://communities.sas.com/t5/SAS-Community-Nordic/Juletip-1-Finding-Missing-data/m-p/523796#M223</link>
    <description>&lt;P&gt;Sorry to pollute the interwebs but I liked this so much that I wrote a macro for myself.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;1. It counts the number of missing vales for all variables in a dataset--both numeric and character&lt;/P&gt;
&lt;P&gt;2. Prints a pattern of missingness for all variables that have at least one missing value starting on the left with the most-missing variable and displaying variables to the right with decreasing amount of missingness.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Maybe some of you will find it useful:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro Missingness(LibName,MemName);
proc format;
    value missing    .='M' other = ' ';
    value $missing ' '='M' other = ' ';
run;

proc sql noprint;
	select cat('sum(cmiss(',strip(Name),'))',' as ',strip(Name)) into :CVars separated by ','
	from dictionary.columns
	where libname=upcase("&amp;amp;LibName") AND memname=upcase("&amp;amp;MemName")
		AND Type='char'
;
	select cat('nmiss(',strip(Name),')',' as ',strip(Name)) into :NVars separated by ','
	from dictionary.columns
	where libname=upcase("&amp;amp;LibName") AND memname=upcase("&amp;amp;MemName")
		AND Type='num'
;
	create table missingness as
	select &amp;amp;CVars, &amp;amp;NVars
	from SASHelp.Heart;
quit;

proc transpose data=missingness
				out=MissingT(rename=(_Name_=Variable Col1=NMiss));
	format NMiss comma.;
run;

proc sql;
	select * from MissingT order by NMiss desc
;
	reset noprint
;
	select Variable into :Vars separated by '*'
	from MissingT
	where NMiss GT 0
	order by NMiss desc
;
&amp;nbsp;&amp;nbsp;&amp;nbsp; drop table Missingness&lt;BR /&gt;;&lt;BR /&gt;quit;

proc freq data=&amp;amp;LibName..&amp;amp;MemName;
    tables &amp;amp;Vars  / list missing;
    format _character_ $missing. _numeric_ missing.; 
run;

%mend Missingness;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 28 Dec 2018 19:55:11 GMT</pubDate>
    <dc:creator>Haris</dc:creator>
    <dc:date>2018-12-28T19:55:11Z</dc:date>
    <item>
      <title>Juletip #1 - Finding Missing data</title>
      <link>https://communities.sas.com/t5/SAS-Community-Nordic/Juletip-1-Finding-Missing-data/m-p/518002#M191</link>
      <description>&lt;P&gt;Hi All&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Welcome back to another season of SAS Juletip&amp;nbsp;&lt;span class="lia-unicode-emoji" title=":winking_face:"&gt;😉&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;This year we will have Juletips&amp;nbsp;every working day in December, and even some days with two Juletip.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;All Juletip&amp;nbsp;will be tagged, and you can find all the&amp;nbsp;Juletip&amp;nbsp;from previous years in the community:&lt;/P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="83"&gt;
&lt;P&gt;&lt;STRONG&gt;2014&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="83"&gt;
&lt;P&gt;&lt;STRONG&gt;2015&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="83"&gt;
&lt;P&gt;&lt;STRONG&gt;2016&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="83"&gt;
&lt;P&gt;&lt;STRONG&gt;2017&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="83"&gt;
&lt;P&gt;&lt;STRONG&gt;2018&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="83"&gt;
&lt;P&gt;&lt;A href="https://communities.sas.com/t5/tag/juletip2014/tg-p" target="_blank"&gt;38&lt;/A&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="83"&gt;
&lt;P&gt;&lt;A href="https://communities.sas.com/t5/tag/juletip2015/tg-p" target="_blank"&gt;17&lt;/A&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="83"&gt;
&lt;P&gt;&lt;A href="https://communities.sas.com/t5/tag/juletip2016/tg-p" target="_blank"&gt;17&lt;/A&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="83"&gt;
&lt;P&gt;&lt;A href="https://communities.sas.com/t5/tag/juletip2017/tg-p" target="_blank"&gt;16&lt;/A&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="120"&gt;
&lt;P&gt;(&lt;A href="https://communities.sas.com/t5/tag/juletip2018/tg-p" target="_blank"&gt;new every day&lt;/A&gt;)&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;Please comment, like and share the SAS juletip&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;----------------------------------------------------------------------------&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Juletip #1 - Finding Missing data&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Sometimes when you work with data you need to get a quick&amp;amp;dirty overview of the data quality - i.e. in regards to missing values.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Today's tip introduces 4 simple ways to get a fast overview and with other small tips introduced along the way.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;1) Quality overview of your numeric variables using PROC MEANS;&lt;/STRONG&gt;&lt;/U&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;PROC MEANS data=Sashelp.Heart nolabels NMISS N stackodsoutput;
  var _NUMERIC_; * Being lazy not specifing the individual variables *;
  ods output Summary = MissingValues;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Notice the output table being made with ods and not "output out=" syntax. The option&amp;nbsp;&lt;A href="https://go.documentation.sas.com/?cdcId=pgmsascdc&amp;amp;cdcVersion=9.4_3.3&amp;amp;docsetId=proc&amp;amp;docsetTarget=n1qnc9bddfvhzqn105kqitnf29cp.htm&amp;amp;locale=en" target="_blank"&gt;stackodsoutput&lt;/A&gt; controls how the output looks&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You could then create a&amp;nbsp;list of problem variables with missing values for later use - if needed&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql noprint;&lt;BR /&gt; select Variable into :MissingVarList separated by ' '&lt;BR /&gt; from MissingValues&lt;BR /&gt; where NMiss &amp;gt; 0;&lt;BR /&gt;quit;&lt;BR /&gt;%put &amp;amp;=MissingVarList;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;2) Using Data step&lt;/STRONG&gt; &lt;/U&gt;&lt;BR /&gt;The &lt;A href="https://go.documentation.sas.com/?cdcId=pgmsascdc&amp;amp;cdcVersion=9.4_3.3&amp;amp;docsetId=lefunctionsref&amp;amp;docsetTarget=p06ybg84o0asa4n17l9ieauk58hb.htm&amp;amp;locale=en" target="_blank"&gt;missing()&lt;/A&gt; function has been around for many SAS version, but not many are using its siblings nmiss &amp;amp; cmiss&lt;BR /&gt;&lt;A href="https://go.documentation.sas.com/?docsetId=lefunctionsref&amp;amp;docsetTarget=p0nw8trwk5ooesn1o8zrtd5c6j1t.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en" target="_blank"&gt;nmiss()&lt;/A&gt; count numeric missing&lt;BR /&gt;&lt;A href="https://go.documentation.sas.com/?docsetId=lefunctionsref&amp;amp;docsetTarget=p1tth4ltf640din1ey86ubo2lky2.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en" target="_self"&gt;cmiss()&lt;/A&gt; count not Char Missing, but Count Missing of both numeric and char variables - making is more useful&lt;/P&gt;
&lt;P&gt;When adding all available variables to arrays, we can refer to them automatically without specifying each of them (lazy approach)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _NULL_;
  set sashelp.heart;
  array char[*} $ _CHAR_;
  array num[*} _NUMERIC_;
  if cmiss(of char[*], of num[*]) then put 'Missing:' _n_ char[*]=;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Notice the summarization &lt;A href="https://go.documentation.sas.com/?docsetId=lestmtsref&amp;amp;docsetTarget=n00gp8yc3x6rcgn1la2w81ru9lb6.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en" target="_blank"&gt;of all variables in the array&lt;/A&gt;, and the put of all variables in the log. You could of course&amp;nbsp;output the same to a dataset. Looping etc.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;3) Outputting the variable name with missing values&lt;/STRONG&gt;&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;This example loop through the variables and only output the variable names (&lt;A href="https://go.documentation.sas.com/?docsetId=ds2ref&amp;amp;docsetTarget=p1c89su8672vtyn17lhjqxci3f45.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en" target="_blank"&gt;vname&lt;/A&gt;) that contain missing values for each obs&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data Missing(keep=obsno name);
  set Sashelp.Heart nobs=nobs;
  array char[*} $ _CHAR_;
  array num[*} _NUMERIC_;
  obsno=_n_;
  length name $32;             
   do i=1 to dim(char);
      if cmiss(char[i]) then 
        do;
          name = vname(char{i});
          output;
        end; 
   end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;4) Using&amp;nbsp;proc freq with formats&lt;/STRONG&gt;&lt;/U&gt;&lt;BR /&gt;An alternative solution using &lt;A href="https://go.documentation.sas.com/?docsetId=proc&amp;amp;docsetTarget=p1xidhqypi0fnwn1if8opjpqpbmn.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en" target="_blank"&gt;formats&lt;/A&gt; and proc freq&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;First setup a dummy format to distinguish between missings and not missing.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc format;
    value missing    .='Missing' other = 'Has Value';
    value $missing ' '='Missing' other = 'Has Value';
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Here we aggregate all values to two groups based on the format&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;ods output OneWayFreqs=freqs;
*ods trace on; * Use this to identify output tabels in ODS*; 
 
proc freq data=sashelp.heart;
    tables _all_/missing;
    format _character_ $missing. _numeric_ missing.; 
run;
*ods trace off;
ods output close;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This tip also outputs the result using &lt;A href="https://go.documentation.sas.com/?docsetId=odsug&amp;amp;docsetTarget=p0oxrbinw6fjuwn1x23qam6dntyd.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en" target="_blank"&gt;ODS output&lt;/A&gt; in a different way than in example&amp;nbsp;1.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Question&lt;/STRONG&gt;: These small snippets are just examples,&amp;nbsp;How would you get this overview of missing values in your data? add a comment below.&lt;/P&gt;</description>
      <pubDate>Mon, 03 Dec 2018 10:44:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Community-Nordic/Juletip-1-Finding-Missing-data/m-p/518002#M191</guid>
      <dc:creator>GertNissen</dc:creator>
      <dc:date>2018-12-03T10:44:29Z</dc:date>
    </item>
    <item>
      <title>Re: Juletip #1 - Finding Missing data</title>
      <link>https://communities.sas.com/t5/SAS-Community-Nordic/Juletip-1-Finding-Missing-data/m-p/518256#M192</link>
      <description>&lt;P&gt;I like the &lt;A href="https://documentation.sas.com/?docsetId=statug&amp;amp;docsetTarget=statug_mi_syntax01.htm&amp;amp;docsetVersion=14.3&amp;amp;locale=en#statug.mi.nimputeopt" target="_self"&gt;MI Procedure&lt;/A&gt;&amp;nbsp;for&amp;nbsp;a nice overview of missing value patterns in numeric variables&amp;nbsp;with the displaypattern=nomeans option (requires SAS 9.4m5)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc mi data=Sashelp.Heart nimpute=0 displaypattern=nomeans;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Looking forward to&amp;nbsp;a lot of SAS juetips &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 03 Dec 2018 22:21:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Community-Nordic/Juletip-1-Finding-Missing-data/m-p/518256#M192</guid>
      <dc:creator>PeterClemmensen</dc:creator>
      <dc:date>2018-12-03T22:21:10Z</dc:date>
    </item>
    <item>
      <title>Re: Juletip #1 - Finding Missing data</title>
      <link>https://communities.sas.com/t5/SAS-Community-Nordic/Juletip-1-Finding-Missing-data/m-p/523792#M222</link>
      <description>&lt;P&gt;Here's the marriage of the two posts above that displays a pattern of missingness similar to PROC MI for both numeric and character vars:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc format;
    value missing    .='M' other = ' ';
    value $missing ' '='M' other = ' ';
run;
proc sql noprint;
	select Name into :Vars separated by '*'
	from dictionary.columns
	where libname='SASHELP' AND memname='HEART';
quit;
proc freq data=sashelp.heart;
    tables &amp;amp;Vars / list missing;
    format _character_ $missing. _numeric_ missing.; 
run;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 28 Dec 2018 19:06:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Community-Nordic/Juletip-1-Finding-Missing-data/m-p/523792#M222</guid>
      <dc:creator>Haris</dc:creator>
      <dc:date>2018-12-28T19:06:02Z</dc:date>
    </item>
    <item>
      <title>Re: Juletip #1 - Finding Missing data</title>
      <link>https://communities.sas.com/t5/SAS-Community-Nordic/Juletip-1-Finding-Missing-data/m-p/523796#M223</link>
      <description>&lt;P&gt;Sorry to pollute the interwebs but I liked this so much that I wrote a macro for myself.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;1. It counts the number of missing vales for all variables in a dataset--both numeric and character&lt;/P&gt;
&lt;P&gt;2. Prints a pattern of missingness for all variables that have at least one missing value starting on the left with the most-missing variable and displaying variables to the right with decreasing amount of missingness.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Maybe some of you will find it useful:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro Missingness(LibName,MemName);
proc format;
    value missing    .='M' other = ' ';
    value $missing ' '='M' other = ' ';
run;

proc sql noprint;
	select cat('sum(cmiss(',strip(Name),'))',' as ',strip(Name)) into :CVars separated by ','
	from dictionary.columns
	where libname=upcase("&amp;amp;LibName") AND memname=upcase("&amp;amp;MemName")
		AND Type='char'
;
	select cat('nmiss(',strip(Name),')',' as ',strip(Name)) into :NVars separated by ','
	from dictionary.columns
	where libname=upcase("&amp;amp;LibName") AND memname=upcase("&amp;amp;MemName")
		AND Type='num'
;
	create table missingness as
	select &amp;amp;CVars, &amp;amp;NVars
	from SASHelp.Heart;
quit;

proc transpose data=missingness
				out=MissingT(rename=(_Name_=Variable Col1=NMiss));
	format NMiss comma.;
run;

proc sql;
	select * from MissingT order by NMiss desc
;
	reset noprint
;
	select Variable into :Vars separated by '*'
	from MissingT
	where NMiss GT 0
	order by NMiss desc
;
&amp;nbsp;&amp;nbsp;&amp;nbsp; drop table Missingness&lt;BR /&gt;;&lt;BR /&gt;quit;

proc freq data=&amp;amp;LibName..&amp;amp;MemName;
    tables &amp;amp;Vars  / list missing;
    format _character_ $missing. _numeric_ missing.; 
run;

%mend Missingness;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 28 Dec 2018 19:55:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Community-Nordic/Juletip-1-Finding-Missing-data/m-p/523796#M223</guid>
      <dc:creator>Haris</dc:creator>
      <dc:date>2018-12-28T19:55:11Z</dc:date>
    </item>
  </channel>
</rss>

