This week, instead of starting over from scratch with a new task, we will be making improvements on last week's Point Estimate Calculator task. Check out last week's post for details on how to get this task started. To improve the task, we want the user to be able to select 2 variables for which to calculate estimates. We also want the user to be able to round their estimates to their desired decimal place, as well as be able to specify a where clause to subset their data.
Here's what it's going to look like when we're done:
We want users to be able to subset their data using a where clause. For this, we will use a textbox. The texbox control has many options in Metadata with it, such as promptMessage. One that we aren't using here is missingMessage, that will be displayed in a red box if the user fails to put something in the textbox. We aren't using that option because the where clause is optional in this task. It's also helpful to attach a label to the textbox with an example as well, so they will know not to enter the "where" or the semi-colon into the box.
In the Code template, we surround our where clause and $textWHERE variable with an if statement, because we don't want the where clause to appear if the user hasn't typed anything.
Metadata:
<Option inputType="string" name="GROUPWHERE">OPTIONAL WHERE CLAUSE</Option>
<Option inputType="string" name="labelWHERE">Enter a where clause if you would like to subset your data. Example: sex = 'F'</Option>
<Option defaultValue="" indent="1" inputType="inputtext" name="textWHERE" promptMessage="Enter a where clause" required="false">Where clause:</Option>
UI:
<Group open="true" option="GROUPWHERE">
<OptionItem option="labelWHERE"/>
<OptionItem option="textWHERE"/>
</Group>
Code Template:
data copy;
set $DATASOURCE;
#if ($textWHERE.length() > 0) where $textWHERE; #end
run;
We want users to be able to get point estimates for not just one variable, but two variables. To run the task, the user must select at least one variable, so in Metadata roles portion for that control we have typed minVars="1". However, the second variable is optional, so in the code for this control we have typed minVars="0".
In the Code Template, we use a foreach to access the variable inside of the role selector. If you try to use $VAR2 without using a foreach, the variable will be in [brackets] in your code.
Metadata:
<DataSources>
<DataSource name="DATASOURCE">
<Roles>
<Role maxVars="1" minVars="1" name="VAR" order="true" type="N">Variable:</Role>
<Role maxVars="1" minVars="0" name="VAR2" order="true" type="N">Optional Second Variable:</Role>
</Roles>
</DataSource>
</DataSources>UI:
UI:
<Group open="true" option="ROLESGROUP">
<RoleItem role="VAR"/>
<RoleItem role="VAR2"/>
</Group>
Code Template:
(The $VAR2 variable is used in other places in the code template as well, download the full code at the bottom to check those out)
#if ($VAR2.size() > 0)
#foreach ( $item2 in $VAR2 )
%let item2 = $item2;
proc means data = copy noprint;
var $item2;
output out = means2 (drop = _TYPE_ _FREQ_)
#if ($chkMEAN == 1) mean = &item2._mean #end
#if ($chkMIN == 1) min = &item2._min #end
#if ($chkMAX == 1) max = &item2._max #end
#if ($chkSTD == 1) std = &item2._std #end
#if ($chkLCLM == 1) LCLM = &item2._LCLM #end
#if ($chkUCLM == 1) UCLM = &item2._UCLM #end
#if ($chkP25 == 1) p25 = &item2._p25 #end
#if ($chkP75 == 1) p75 = &item2._p75 #end
;
run;
#end #end
We want the user to be able to select how many decimal places they would like their mea, upper confidence limit, and lower confidence limit rounded to. The SAS round function requires .01 if you'd like to round to 2 decimal places, but this may not be intuitive for the user. Therefore it is important to remember that with a combobox, the name="" is what is inserted into your code, and the text in between the >arrows< is what will be shown in the task.
Metadata:
<Option inputType="string" name="GROUPCOMBO">ROUNDING</Option>
<Option defaultValue=".0" inputType="combobox" name="roundCOMBO">Select the number of decimal places that you would like your output statistics to be rounded to.</Option>
<Option inputType="string" name="1">0</Option>
<Option inputType="string" name="0.1">1</Option>
<Option inputType="string" name="0.01">2</Option>
<Option inputType="string" name="0.001">3</Option>
<Option inputType="string" name="0.0001">4</Option>
<Option inputType="string" name="0.00001">5</Option>
<Option inputType="string" name="0.000001">6</Option>
UI:
<Group open="true" option="GROUPCOMBO">
<OptionChoice option="roundCOMBO">
<OptionItem option="1"/>
<OptionItem option="0.1"/>
<OptionItem option="0.01"/>
<OptionItem option="0.001"/>
<OptionItem option="0.0001"/>
<OptionItem option="0.00001"/>
<OptionItem option="0.000001"/>
</OptionChoice>
</Group>
Code Template:
#if ($VAR2.size() < 0)
data point;
set point1;
#if ($chkMEAN == 1) &item._mean = round(&item._mean, $roundCOMBO); #end
#if ($chkLCLM == 1) &item._lclm = round(&item._lclm, $roundCOMBO); #end
#if ($chkUCLM == 1) &item._uclm = round(&item._uclm, $roundCOMBO); #end
run;
#end
#if ($VAR2.size() > 0)
data point2;
set copy;
if _n_ = 1 then
set means2;
run;
data point;
merge point1 point2;
#if ($chkMEAN == 1) &item._mean = round(&item._mean, $roundCOMBO); #end
#if ($chkLCLM == 1) &item._lclm = round(&item._lclm, $roundCOMBO); #end
#if ($chkUCLM == 1) &item._uclm = round(&item._uclm, $roundCOMBO); #end
#if ($chkMEAN == 1) &item2._mean = round(&item2._mean, $roundCOMBO); #end
#if ($chkLCLM == 1) &item2._lclm = round(&item2._lclm, $roundCOMBO); #end
#if ($chkUCLM == 1) &item2._uclm = round(&item2._uclm, $roundCOMBO); #end
run;
#end
We've made significant improvements to the Point Estimate Calculator task that make it easier to use and much more functional. Click the button to save, then click the
button to open the task. Make your selections, then click
again to watch it run!
Get the code from the zip file at the end of this article or from GitHub.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.