<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>SAS Users</title>
	
	<link>https://blogs.sas.com/content/sgf</link>
	<description>Providing technical tips and support information, written for and by SAS users.</description>
	<lastBuildDate>Fri, 12 Nov 2021 19:12:58 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.3</generator>
	<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/SasGlobalForumBlog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="sasglobalforumblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">SasGlobalForumBlog</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">https://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Creating Simulated Data Sets (Part Two)</title>
		<link>https://blogs.sas.com/content/sgf/2021/11/16/creating-simulated-data-sets-part-two/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/11/16/creating-simulated-data-sets-part-two/#respond</comments>
		
		<dc:creator><![CDATA[Ron Cody]]></dc:creator>
		<pubDate>Tue, 16 Nov 2021 13:12:01 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[box plot]]></category>
		<category><![CDATA[SAS OnDemand for Academics]]></category>
		<category><![CDATA[simulated data]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=36510</guid>

					<description><![CDATA[<p>This blog is a continuation of a previous blog that discussed creating simulated data sets. If you have not seen it, you might want to review it, especially if you are not familiar with the RAND function. The program that I'm going to show you simulates a drug study with [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/16/creating-simulated-data-sets-part-two/">Creating Simulated Data Sets (Part Two)</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This blog is a continuation of a <a href="https://blogs.sas.com/content/sgf/2021/11/02/creating-simulated-data-sets/">previous blog</a> that discussed creating simulated data sets. If you have not seen it, you might want to review it, especially if you are not familiar with the RAND function.</p>
<p>The program that I'm going to show you simulates a drug study with three groups (Placebo, Drug A, and Drug B), two genders, and correlated values of systolic blood pressure (SBP) and diastolic blood pressure (DBP).</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">proc <span style="color: #0000ff;">format</span>; ❶
   value $Gender <span style="color: #a020f0;">'0'</span> = <span style="color: #a020f0;">'Male'</span>
                 <span style="color: #a020f0;">'1'</span> = <span style="color: #a020f0;">'Female'</span>;
<span style="color: #000080; font-weight: bold;">run</span>;
&nbsp;
<span style="color: #000080; font-weight: bold;">data</span> Study;
   <span style="color: #0000ff;">call</span> streaminit<span style="color: #66cc66;">&#40;</span><span style="color: #2e8b57; font-weight: bold;">13579</span><span style="color: #66cc66;">&#41;</span>; ❷
   <span style="color: #0000ff;">do</span> i = <span style="color: #2e8b57; font-weight: bold;">1</span> to <span style="color: #2e8b57; font-weight: bold;">30</span>;
      <span style="color: #0000ff;">do</span> Drug = <span style="color: #a020f0;">'Placebo'</span>,<span style="color: #a020f0;">'Drug A'</span>,<span style="color: #a020f0;">'Drug B'</span>; ❸
         Subjec + <span style="color: #2e8b57; font-weight: bold;">1</span>; ❹
         Gender = <span style="color: #0000ff;">put</span><span style="color: #66cc66;">&#40;</span>rand<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'Bernoulli'</span>,.5<span style="color: #66cc66;">&#41;</span>,<span style="color: #2e8b57; font-weight: bold;">1</span>.<span style="color: #66cc66;">&#41;</span>; ❺
         SBP = rand<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'Normal'</span>,<span style="color: #2e8b57; font-weight: bold;">160</span>,<span style="color: #2e8b57; font-weight: bold;">10</span><span style="color: #66cc66;">&#41;</span> - <span style="color: #2e8b57; font-weight: bold;">20</span><span style="color: #006400; font-style: italic;">*(Drug = 'Drug A') ❻
            - 30*(Drug = 'Drug B') - 5*(Gender = '1');</span>
         DBP = .5<span style="color: #006400; font-style: italic;">*SBP + 40*rand('Uniform');</span> ❼
&nbsp;
         SBP = <span style="color: #0000ff;">round</span><span style="color: #66cc66;">&#40;</span>SBP<span style="color: #66cc66;">&#41;</span>; ❽
         DBP = <span style="color: #0000ff;">round</span><span style="color: #66cc66;">&#40;</span>DBP<span style="color: #66cc66;">&#41;</span>;
         <span style="color: #0000ff;">output</span>;
      <span style="color: #0000ff;">end</span>;
   <span style="color: #0000ff;">end</span>;
   <span style="color: #0000ff;">drop</span> i;
   <span style="color: #0000ff;">format</span> Gender $Gender.;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>❶ Create a character format that will be used to format Gender.<br />
❷ Because this is a drug study, you want to be able to reproduce the same random sequence at a later time. If you use the same argument in CALL STREAMINIT in another program, you will create identical random streams.<br />
❸ Remember that SAS DO LOOPS can use character values. This is very handy.<br />
❹ This SUM statement is generating the variable Subject.<br />
❺ The Bernoulli distribution with the second argument set to .5, will assign gender (0 or 1) with a probability of .5 for both. The PUT function in this statement is doing a numeric-to-character conversion.<br />
❻ This is a very interesting statement. You start by choosing values for SBP from a normal distribution with a mean of 160 and a standard deviation of 10. The logical expressions such as (Drug = 'Drug A') returns a 1 if the expression if true and 0 otherwise. By multiplying this by a numeric value, you can adjust the means in the three groups. The Placebo group will have a mean close to 160—the subjects in drug group A will be approximately 20 points lower than the Placebo group and the subjects in drug group B will be approximately 30 points lower than the Placebo group. Finally, females will be approximately 5 points lower than males.<br />
❼ DBP will be correlated with SBP because it includes a proportion of SBP in the calculation. (See the previous simulated data blog for more details about generating correlated pairs.)<br />
❽ Although I could have added the ROUND function when SBP and DBP were created, it makes the program a bit easier to read by rounding the values in separate statements.<br />
The figure below shows the first nine observations in the simulated Study data set. This figure as well as all the box plots and the scatter plot that follow, were created using built-in SAS Studio tasks in the cloud version called SAS OnDemand for Academics.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Cody_1_Sim_2.jpg"><img loading="lazy" class="alignnone size-medium wp-image-36513" src="https://blogs.sas.com/content/sgf/files/2021/11/Cody_1_Sim_2-300x276.jpg" alt="" width="300" height="276" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Cody_1_Sim_2-300x276.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_1_Sim_2.jpg 627w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>The next figure is a box plot with SBP as the displayed variable. As a quick review, a box plot shows a vertical line at the median (in the middle of the box). The lower and upper edges of the box represent values at the 25<sup>th</sup> and 75<sup>th</sup> percentile respectively. The diamond in the box represents the mean. The distance between the 25<sup>th</sup> and 75<sup>th</sup> percentiles is called the inter-quartile range. Finally, any points more than 1.5 inter-quartile ranges below the 25<sup>th</sup> percentile or above the 75<sup>th</sup> percentile are plotted as circles and considered outliers. You can see one outlier in the placebo group in the left portion of the box plot below.</p>
<p>Notice that the means are approximately where you expect them to be (Placebo around 160, Drug A around 140, and Drug B around 130. The means are slightly lower because half of the subjects are female and their systolic blood pressures were designed to be approximately 5 points lower than the males.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Cody_2_Sim_2.jpg"><img loading="lazy" class="alignnone size-medium wp-image-36516" src="https://blogs.sas.com/content/sgf/files/2021/11/Cody_2_Sim_2-300x223.jpg" alt="" width="300" height="223" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Cody_2_Sim_2-300x223.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_2_Sim_2-1024x763.jpg 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_2_Sim_2-768x572.jpg 768w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_2_Sim_2.jpg 1035w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Here is a plot of SBP by Gender.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Cody_3_Sim_2.jpg"><img loading="lazy" class="alignnone size-medium wp-image-36519" src="https://blogs.sas.com/content/sgf/files/2021/11/Cody_3_Sim_2-300x226.jpg" alt="" width="300" height="226" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Cody_3_Sim_2-300x226.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_3_Sim_2-1024x771.jpg 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_3_Sim_2-768x578.jpg 768w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_3_Sim_2.jpg 1043w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>The last figure is a plot of SBP by DBP. Notice that the values are correlated (the Pearson r is approximately .64).</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Cody_4_Sim_2.jpg"><img loading="lazy" class="alignnone size-medium wp-image-36522" src="https://blogs.sas.com/content/sgf/files/2021/11/Cody_4_Sim_2-300x227.jpg" alt="" width="300" height="227" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Cody_4_Sim_2-300x227.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_4_Sim_2-1024x773.jpg 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_4_Sim_2-768x580.jpg 768w, https://blogs.sas.com/content/sgf/files/2021/11/Cody_4_Sim_2.jpg 1049w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Using techniques similar to this program, combined with methods in the previous simulation blog, you should be able to create your own custom simulated data sets.</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/16/creating-simulated-data-sets-part-two/">Creating Simulated Data Sets (Part Two)</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=7gmdR51ahIc:GaLX9WvXqFk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=7gmdR51ahIc:GaLX9WvXqFk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=7gmdR51ahIc:GaLX9WvXqFk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=7gmdR51ahIc:GaLX9WvXqFk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=7gmdR51ahIc:GaLX9WvXqFk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=7gmdR51ahIc:GaLX9WvXqFk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=7gmdR51ahIc:GaLX9WvXqFk:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=7gmdR51ahIc:GaLX9WvXqFk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=7gmdR51ahIc:GaLX9WvXqFk:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/11/16/creating-simulated-data-sets-part-two/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/11/Cody_4_Sim_2-150x150.jpg" />
	</item>
		<item>
		<title>How do people divide their time among daily activities?</title>
		<link>https://blogs.sas.com/content/sgf/2021/11/10/how-do-people-divide-their-time-among-daily-activities/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/11/10/how-do-people-divide-their-time-among-daily-activities/#respond</comments>
		
		<dc:creator><![CDATA[Cindy Wang]]></dc:creator>
		<pubDate>Wed, 10 Nov 2021 12:30:04 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[SAS Visual Analytics]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=36381</guid>

					<description><![CDATA[<p>SAS' Cindy Wang uses SAS Visual Analytics to explore how people around the world spend their days.</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/10/how-do-people-divide-their-time-among-daily-activities/">How do people divide their time among daily activities?</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Time is a free resource to people yet is the most precious one. We all have 24 hours every day in our lives. We do not need to pay for getting these hours, and we do not have ways to pay for getting more than 24 hours a day. Have you ever noticed how you spend your time? Or how other people spend their time?</p>
<p>Certainly, there will be commonalities – for example, all people need time to sleep, to eat and many people need time to work and study. Also, for sure there are differences in how people divide their time for activities in each day. There might be some pattern of time use in different countries and different cultures. I am interested in exploring this, so I found some data from the web to explore.</p>
<h2><strong>What is a Time Use Survey?</strong></h2>
<p>Over the last 30 years, an increasing number of countries around the world have been conducting large-scale time use surveys. The Time Use Survey is designed to measure the amount of time people spend on various activities in their daily life, across a total duration of 24 hours (or 1,440 minutes). These activities, such as work, relaxing, and exercising, are classified into a set of descriptive categories, and the time on these activities are interviewed from some respondents. Then the data was recorded, calculated and edited.</p>
<p>I got the time use data from OECD (Organization for Economic Co-operation and Development) site, and the time use survey was conducted in more than 30 countries from 2009 to 2016. I also got the American Time Use Survey data for 2020 for my exploration. I am aware that the data quality might not be good enough for serious research, but that’s not a problem for me. I just want to explore it for fun, while practicing SAS Visual Analytics usage.</p>
<h2><strong>How do people around the world spend their time?</strong></h2>
<p>Download the excel file from <a href="https://stats.oecd.org/Index.aspx?DataSetCode=TIME_USE">OECD site</a>, import it in SAS Visual Analytics. I will explore how people in different countries spend their time, how many minutes do they averagely spend on among the five categories (according to OECD, they put different activities into five categories).</p>
<p>We can easily draw a bar chart in SAS VA like below. Note: the downloaded OECD data has the time use data for American, but I eliminate it from this chart due to its total is 1,469 minutes (more than 24 hours a day). And that leads me to explore the American time use data separately.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-36387" src="https://blogs.sas.com/content/sgf/files/2021/11/Figure-1.png" alt="" width="1436" height="814" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Figure-1.png 1436w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-1-300x170.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-1-1024x580.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-1-768x435.png 768w" sizes="(max-width: 1436px) 100vw, 1436px" /></p>
<p>See the green bars are the longest one among the five colored bars? They represent Personal Care. It seems people across these countries pay the most time in Personal Care. Unbelievable? Check the activities in the Personal Care category: sleeping, eating, dressing, and others personal care activities. All right, people sleep about 8 hours (480 mins) every day on average, that’s about 30% of a day. It makes sense that the Personal Care category occupies the most time (about 661 mins on average) in our daily life.</p>
<p>Now from another perspective, let’s see the top and bottom countries where people spend time on Personal Care, as well as on paid work/study. From below charts, I guess you won’t be surprised when seeing France sits on the top one country with most Personal Care time, and Japan sits on the top one country with most time on paid work/study, while Italy is the country where people spend least time on paid work/study.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-36390" src="https://blogs.sas.com/content/sgf/files/2021/11/Figure-2.png" alt="" width="1004" height="788" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Figure-2.png 1004w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-2-300x235.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-2-768x603.png 768w" sizes="(max-width: 1004px) 100vw, 1004px" /></p>
<p>Note in above charts, I use the same scale for the X axis intentionally. This is to make sure people get direct feel on the differences between the two categories, the ‘Paid work or study’ time on the right is less than half of the ‘Personal Care’ time on the left.</p>
<p>Furthermore, we can look at the distribution of these five categories across all these countries. Calculate the percentage for each major category using calculated items in VA and show them in a box plot. We see people on average spend about 46% of their time on Personal Care, about 20% on Leisure, and 19% on Paid work/study. The highest percentage in ‘Personal Care’ is about 52%, more than 12 hours every day. The least percentage is about 42%, that’s about 10 hours every day. Also notice that time on Personal Care, Leisure and Paid work/study are the top 3 categories that takes more than 85% time each day.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-36393" src="https://blogs.sas.com/content/sgf/files/2021/11/Figure-3.png" alt="" width="367" height="557" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Figure-3.png 367w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-3-198x300.png 198w" sizes="(max-width: 367px) 100vw, 367px" /></p>
<h2><strong>How do</strong><strong> Americans spend their time?</strong></h2>
<p>As I mentioned, the American data from OECD is not ideal for me, so I downloaded the <a href="https://www.bls.gov/tus/data.htm">American Time Use Survey (ATUS) data</a>, and using the 2020 data file for further exploration. The ATUS data was organized in different categories using different methodology than OECD data, so I must do data preparation in SAS Studio, and then explore in SAS Visual Analytics.</p>
<h2><strong>Prepare the data</strong></h2>
<p>The raw 2020 data file has 399 columns, and 8,782 rows. It contains data for the total number of minutes that each respondent spent on the 6-digit activity (per <a href="https://www.bls.gov/tus/tu2020coderules.pdf">ATUS code rule</a>). The column names with the letter "t" precedes the 6-digit codes, identify activities by their 6-digit codes. The first and second digits of the 6-digit code correspond to some tier1 code; the second and third digits correspond to some tier 2 code, etc. Each row corresponds to a unique respondent.</p>
<p>So my data preparation includes:</p>
<ul>
<li>Classify the 6-digit activities to their corresponding tier1 codes, which comes to about 18 categories.</li>
<li>Calculate the means and 99% confidence interval for each of the 18 categories.</li>
<li>Transpose the dataset and merge the datasets. If you are interested in how I did this, you <a href="https://github.com/sbjciw/TUS/blob/main/ATUS_PREP.SAS">can get the code on GitHub</a>..</li>
<li>The ATUS data set contains one column on Age, so I can make a custom category of age group in VA and divide the ages to three categories: less than 18, great than 65, and between 18 and 65. This will enable me to compare the ATUS data with the OECD data (whose ages are between 18 and 65).</li>
</ul>
<h2><strong>Aggregate the data</strong></h2>
<p>ATUS contains detailed data from thousands of respondents with hundreds of columns. I need to aggregate the data for my exploration. Here are some tips when doing the aggregation for each of these hundreds of columns:</p>
<ol>
<li>The default aggregation for measure items in VA is Sum. We can easily change the aggregation in the data pane by clicking the ‘Edit properties’ icon and choosing other aggregation (I will use ‘Average’) in the ‘Aggregation’ dropdown list. But when I have hundreds of measure items in the ATUS data set, how can I quickly set the average aggregation for them instead of one-by-one? The tip is clicking on the first measure item, and scroll to the last item, press ‘shift’ when clicking the last item. This will select all these measure items. Right click the mouse, and from the pop-up menu, choose Aggregation &gt; Average. This will set the aggregation to average for all the chosen items.</li>
<li>I need a bunch of calculated items; each comprise lots of measure items. In SAS Visual Analytics, we can manually add each item in visual mode. But it’s too tedious to add so many measure items. The tip here is to write some SAS macro codes to generate the calculation expressions in text for me, then copy/paste the expression in text mode.</li>
</ol>
<h2><strong>Explore the data</strong></h2>
<p>According to the <a href="https://www.bls.gov/tus/tu2020coderules.pdf">ATUS code rule</a>, ATUS uses different categories than OECD categories. To be able to compare the time used in major activity categories, I make the similar major activity categories like those from OECD, based on my personal understanding of the ATUS activities. Then with the bunch of calculated items, I get the time for these major activity categories. Due to methodology difference, be aware that this may lead the results to be partially inaccurate.</p>
<p>Now starts my ATUS exploration. Below charts show how people in American divide their daily time. The dataset has information on gender, so the bottom one shows the average percentage for Male and Female respectively.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-36396" src="https://blogs.sas.com/content/sgf/files/2021/11/Figure-4.png" alt="" width="1428" height="349" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Figure-4.png 1428w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-4-300x73.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-4-1024x250.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-4-768x188.png 768w" sizes="(max-width: 1428px) 100vw, 1428px" /></p>
<p>When I put the percentage data (calculated for major activities categories) in a box plot, it has lot of outliers for each category. Considering different methodology and personal classification to the major activity categories (here is the OECD code), I see some difference than the OECD box plot. Note that the ranking for top two major activity categories are Personal Care and Leisure, the same pattern as in OECD data.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-36399" src="https://blogs.sas.com/content/sgf/files/2021/11/Figure-5.png" alt="" width="392" height="574" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Figure-5.png 392w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-5-205x300.png 205w" sizes="(max-width: 392px) 100vw, 392px" /></p>
<h2><strong>Identify the outliers</strong></h2>
<p>Notice those outliers in above box plot? I’d better explore more. In latest version, SAS Visual Analytics will automatically detect outliers in data items. This ‘Insights’ will list the data items in report objects that might be affected by outliers.</p>
<p>For example, in below screenshot, I made a histogram of the ‘Personal Care %’, which shows its distribution looks like normal. If I click the ‘Insight’ icon at top-right corner, VA will show all the data items that might be affected by outliers. If clicking the icon next to the ‘Personal Care %’ item at the bottom, a message will pop up saying that there are 243 outliers in this data item.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-36402" src="https://blogs.sas.com/content/sgf/files/2021/11/Figure-6.png" alt="" width="783" height="627" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Figure-6.png 783w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-6-300x240.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-6-768x615.png 768w" sizes="(max-width: 783px) 100vw, 783px" /></p>
<h2><strong>Create a custom</strong> <strong>graph</strong></h2>
<p>I saw lot of outliers in columns of ATUS data when exploring it, so I decide to use the mean value with confidence intervals. I created a custom graph with a scatter plot and a schedule chart. In SAS VA, assign the black dot in the custom graph to show the mean value and make the beginning and ending of each blue bar show the 99% confidence intervals.</p>
<p>Below is the top 10 ATUS activity categories (here are the ATUS tier 1 code categories) American people spend time on. We see the largest average time is the Personal Care, about 586 mins (nearly 10 hours) with 99% confidence intervals ranging from 583.5 to 588.4 mins.</p>
<p><img loading="lazy" class="alignnone size-full wp-image-36405" src="https://blogs.sas.com/content/sgf/files/2021/11/Figure-7.png" alt="" width="1728" height="333" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Figure-7.png 1728w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-7-300x58.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-7-1024x197.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-7-768x148.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/Figure-7-1536x296.png 1536w" sizes="(max-width: 1728px) 100vw, 1728px" /></p>
<p>That’s my initial exploration of Time Use Survey data, but much more can be done. For example, because ATUS data is collected on an ongoing, monthly basis, we can perform time-series analysis to identify changes in how people spend their time.</p>
<p>Would you like to give it a try? Visit the SAS Visual Analytics Gallery on the SAS Support Communities to see more ways you can use SAS Visual Analytics to explore data. Then sign up for a <a href="https://www.sas.com/en_us/trials/software/visual-data-science-decisioning/viya-trial-form.html">two-week free trial of SAS Visual Analytics</a>. </p>
<a href="https://communities.sas.com/t5/SAS-Visual-Analytics-Gallery/tkb-p/vagallery" class="sc-button sc-button-default"><span><span class="btnheader">EXPLORE NOW | </span> SAS Visual Analytics Gallery</span></a>
<br />
<a href="https://www.sas.com/en_us/trials/software/visual-data-science-decisioning/viya-trial-form.html" class="sc-button sc-button-default"><span><span class="btnheader">START FREE TRIAL | </span> SAS Visual Analytics</span></a>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/10/how-do-people-divide-their-time-among-daily-activities/">How do people divide their time among daily activities?</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=E0t8EC--xXE:y4Wqw-l2rNI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=E0t8EC--xXE:y4Wqw-l2rNI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=E0t8EC--xXE:y4Wqw-l2rNI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=E0t8EC--xXE:y4Wqw-l2rNI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=E0t8EC--xXE:y4Wqw-l2rNI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=E0t8EC--xXE:y4Wqw-l2rNI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=E0t8EC--xXE:y4Wqw-l2rNI:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=E0t8EC--xXE:y4Wqw-l2rNI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=E0t8EC--xXE:y4Wqw-l2rNI:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/11/10/how-do-people-divide-their-time-among-daily-activities/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/11/Figure-1-150x150.png" />
	</item>
		<item>
		<title>How I used a SAS ML model and Intelligent Decisioning to build a calculator</title>
		<link>https://blogs.sas.com/content/sgf/2021/11/09/sas-ml-model-intelligent-decisioning-build-calculator/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/11/09/sas-ml-model-intelligent-decisioning-build-calculator/#respond</comments>
		
		<dc:creator><![CDATA[Pedro Puche]]></dc:creator>
		<pubDate>Tue, 09 Nov 2021 19:25:21 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[linear regression]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[sas intelligent decisioning]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=36231</guid>

					<description><![CDATA[<p>If you are thinking that nobody in their right mind would implement a Calculator API Service with a machine learning model, then yes, you’re probably right. But considering curiosity is in my DNA, it sometimes works this way and machine learning is fun. I have challenged myself to do it, [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/09/sas-ml-model-intelligent-decisioning-build-calculator/">How I used a SAS ML model and Intelligent Decisioning to build a calculator</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>If you are thinking that nobody in their right mind would implement a Calculator API Service with a machine learning model, then yes, you’re probably right. But considering curiosity is in my DNA, it sometimes works this way and machine learning is fun. I have challenged myself to do it, not for the purpose of promoting such an experiment into production, but simply accomplishing a self-challenge that can be easily achieved with the resources provided by SAS Viya, particularly SAS Model Studio and SAS Intelligent Decisioning.</p>
<p>So, first, let’s define the purpose of my challenge:</p>
<h3 style="padding-left: 40px;text-align: right"><span style="color: #0000ff">deploy a basic calculator API service capable of executing the following operations for two input decimal numbers: addition, subtraction, multiplication, and division</span></h3>
<p>The challenge must be executed under these restrictions:</p>
<ul>
<li>Usage of a machine learning model as the “compute-engine” of the calculator</li>
<li>Development under the low code / no code paradigm</li>
<li>The end-to-end setup and execution process should not take more than a couple of hours</li>
</ul>
<p>Use the following tools in SAS Viya:</p>
<ul>
<li>Model Studio</li>
<li>Intelligent Decisioning</li>
<li>Simple web app (set up not covered)</li>
</ul>
<h1>The plan</h1>
<p>The steps that I am identifying to complete my challenge are:<br />
<strong>Step 1 -</strong> Create a machine learning model representing the compute-engine of my calculator (Model Studio)<br />
<strong>Step 2 -</strong> Determine how to process other mathematical operations<br />
<strong>Step 3 -</strong> Step 3 - Embed the needed logic into the decision to perform the calculator operations (Intelligent Decisioning)<br />
<strong>Step 4 -</strong> Publish the artifact created as an API service (web app created outside of this post)</p>
<h2>Step 1. Create a machine learning model as the compute-engine</h2>
<p>Our first step is to create a model. We start with the addition operation and build from there. We’ll perform the addition by normal means of <strong>adding two numbers</strong>. Next, we’ll apply some extra logic which will perform subtraction, multiplication, and division. The diagram below represents the process:<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/figure1_calculator.png"><img loading="lazy" class="aligncenter size-large wp-image-36246" src="https://blogs.sas.com/content/sgf/files/2021/11/figure1_calculator-1024x179.png" alt="" width="702" height="123" srcset="https://blogs.sas.com/content/sgf/files/2021/11/figure1_calculator-1024x179.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/figure1_calculator-300x52.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/figure1_calculator-768x134.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/figure1_calculator.png 1511w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>A machine learning model is built from a data set where it self-learns what to do. I want my model to learn the addition of two numbers. I created a <a href="https://github.com/sascommunities/sas-users-blog/blob/master/calculator-regression-model-decision/CalculatorBasic_Train1.xlsx">training data set in Excel with 100 registers</a>, each of them with two random numbers between 0 and 1 and then the sum of them. The image below displays the general setup:<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/figure2_calculator.png"><img loading="lazy" class="aligncenter size-medium wp-image-36249" src="https://blogs.sas.com/content/sgf/files/2021/11/figure2_calculator-300x127.png" alt="" width="300" height="127" srcset="https://blogs.sas.com/content/sgf/files/2021/11/figure2_calculator-300x127.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/figure2_calculator-351x150.png 351w, https://blogs.sas.com/content/sgf/files/2021/11/figure2_calculator.png 355w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>The algorithm / model I chose for my compute engine is the linear regression. Linear regression is a simple machine learning algorithm based in the following formula:</p>
<p>y = <em>a</em> + <em>b·</em><strong>X<sub>1</sub></strong> + <em>c</em>·<strong>X<sub>2</sub></strong> + <em>d</em>·<strong>X<sub>3</sub></strong> + … + <em>n</em>·<strong>X<sub>n</sub></strong></p>
<p>Where:</p>
<ul>
<li>y is the result of the model execution – the result of the addition operation</li>
<li><strong>X<sub>1</sub></strong>, <strong>X<sub>2</sub></strong>, <strong>X<sub>3</sub></strong>, …, <strong>X<sub>n</sub></strong> are the input variables – for the calculator, there only will be <strong>X<sub>1</sub></strong> and <strong>X<sub>2</sub></strong> as operands</li>
<li><em>a, b, c, d, …, n</em> are the parameters the machine learning process determines to create the model</li>
</ul>
<p>So, with the training data set created, I’ll open a new machine learning project in SAS Viya Model Studio, selecting my data set from where the algorithm will learn, assign the target variable, add linear regression node, a test node, and click “Run pipeline”. Note: if following along in your own environment, make sure to use <code>Selection Method = Adaptive LASSO</code> and toggle <code>Suppress intercept = On</code> in the linear regression node. The resulting model resembles the following:<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/regression_model.png"><img loading="lazy" class="aligncenter size-full wp-image-36357" src="https://blogs.sas.com/content/sgf/files/2021/11/regression_model.png" alt="" width="753" height="444" srcset="https://blogs.sas.com/content/sgf/files/2021/11/regression_model.png 753w, https://blogs.sas.com/content/sgf/files/2021/11/regression_model-300x177.png 300w" sizes="(max-width: 753px) 100vw, 753px" /></a></p>
<p>You can learn more about model creation in the <a href="https://www.youtube.com/watch?v=IGW77r-KQDc">How to Deploy Models in SAS</a> tutorial on the SAS Users YouTube channel.</p>
<p>Once the pipeline completes, and reviewing the initial results, it seems the model is behaving in a proper way; but when I test specific operands where the result is zero, I realize the model has misgivings:<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/figure4_calculator.png"><img loading="lazy" class="aligncenter size-medium wp-image-36264" src="https://blogs.sas.com/content/sgf/files/2021/11/figure4_calculator-300x124.png" alt="" width="300" height="124" srcset="https://blogs.sas.com/content/sgf/files/2021/11/figure4_calculator-300x124.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/figure4_calculator-1024x423.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/figure4_calculator-768x318.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/figure4_calculator-1078x447.png 1078w, https://blogs.sas.com/content/sgf/files/2021/11/figure4_calculator.png 1081w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Those are the operations with zero as result. I think that maybe, the algorithm hasn’t learned with the proper data, so I <a href="https://github.com/sascommunities/sas-users-blog/blob/master/calculator-regression-model-decision/CalculatorBasic_Train2.xlsx">change the first seven registers of my initial dataset</a> with the following operations with zeros:<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/figure5_calculator.png"><img loading="lazy" class="aligncenter size-medium wp-image-36267" src="https://blogs.sas.com/content/sgf/files/2021/11/figure5_calculator-300x188.png" alt="" width="300" height="188" srcset="https://blogs.sas.com/content/sgf/files/2021/11/figure5_calculator-300x188.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/figure5_calculator-343x215.png 343w, https://blogs.sas.com/content/sgf/files/2021/11/figure5_calculator.png 515w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Again, running the pipeline and letting the magic work, <strong>Voila!!!</strong><em>, </em>the process has learned to handle the zeroes and properly sum two input numbers. When I check the results, I verify the results calculated (predicted) by the model are the same as the original ones that were indicated in the training and <a href="https://github.com/sascommunities/sas-users-blog/blob/master/calculator-regression-model-decision/CalculatorBasic_Test.xlsx">test dataset</a>. So now, I am sure my new model is ready for use as my calculator compute engine.</p>
<div class="row cf"><div class="column half"><a href="https://blogs.sas.com/content/sgf/files/2021/11/figure6_calculator.png"><img loading="lazy" class="aligncenter size-full wp-image-36273" src="https://blogs.sas.com/content/sgf/files/2021/11/figure6_calculator.png" alt="" width="690" height="231" srcset="https://blogs.sas.com/content/sgf/files/2021/11/figure6_calculator.png 690w, https://blogs.sas.com/content/sgf/files/2021/11/figure6_calculator-300x100.png 300w" sizes="(max-width: 690px) 100vw, 690px" /></a></div><div class="column half"><a href="https://blogs.sas.com/content/sgf/files/2021/11/figure7_calculator.png"><img loading="lazy" class="aligncenter size-full wp-image-36276" src="https://blogs.sas.com/content/sgf/files/2021/11/figure7_calculator.png" alt="" width="503" height="180" srcset="https://blogs.sas.com/content/sgf/files/2021/11/figure7_calculator.png 503w, https://blogs.sas.com/content/sgf/files/2021/11/figure7_calculator-300x107.png 300w" sizes="(max-width: 503px) 100vw, 503px" /></a></div></div>
<p>Now that I have my compute engine (model) ready, it’s time to use it. We know it can perform the sum operation perfectly, so how do we perform the rest of the operations? We’ll take the sum model, move it into SAS Intelligent Decisioning, and add rules to handle the rest of the operations.</p>
<p>First, let’s explore the logic that will build the operations from our original model. This is where mathematics start playing in (Step 2). After exploring the operations we'll look at the Decision model where we'll define the logic to run the operations (Step 3).</p>
<h3>Addition</h3>
<p>Execute the model with the two input numbers, with no additional logic.<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/additonOp.png"><img loading="lazy" class="aligncenter size-full wp-image-36456" src="https://blogs.sas.com/content/sgf/files/2021/11/additonOp.png" alt="" width="528" height="209" srcset="https://blogs.sas.com/content/sgf/files/2021/11/additonOp.png 528w, https://blogs.sas.com/content/sgf/files/2021/11/additonOp-300x119.png 300w" sizes="(max-width: 528px) 100vw, 528px" /></a></p>
<h3>Subtraction</h3>
<p>By changing the sign of the second input, the model does the rest.<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/subtractionOp.png"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/11/subtractionOp.png" alt="" width="595" height="199" class="aligncenter size-full wp-image-36468" srcset="https://blogs.sas.com/content/sgf/files/2021/11/subtractionOp.png 595w, https://blogs.sas.com/content/sgf/files/2021/11/subtractionOp-300x100.png 300w" sizes="(max-width: 595px) 100vw, 595px" /></a><br />
That’s a simple enough solution for subtraction, but how do we handle multiplication and division? Let’s take a look.</p>
<h3>Multiplication and division</h3>
<p>How can I perform a multiplication or a division operation if my compute engine only executes the addition operation? Here we can apply the magic of logarithmic properties stating:</p>
<ul>
<li>log (x*y) = log(x) + log(y)</li>
<li>log (x/y) = log(x) – log(y)</li>
</ul>
<p>Following this logic, if I want to multiply two numbers, I calculate the logarithm of each one and perform the addition operation in my compute engine. I follow this up by applying the exponential function to reverse the logarithm. The image below outlines the workflow.<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/figure10_calculator.png"><img loading="lazy" class="aligncenter size-large wp-image-36294" src="https://blogs.sas.com/content/sgf/files/2021/11/figure10_calculator-1024x283.png" alt="" width="702" height="194" srcset="https://blogs.sas.com/content/sgf/files/2021/11/figure10_calculator-1024x283.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/figure10_calculator-300x83.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/figure10_calculator-768x212.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/figure10_calculator.png 1301w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>For the division, it is the same process, but changing the sign of the second logarithm to the subtraction operation.</p>
<h3>Additional Logic</h3>
<p>There are also certain cases requiring special treatment. For example, a division by zero generates an error, a logarithm of zero or a negative number cannot be calculated, and the multiplication of two numbers is zero if at least one of them is zero.</p>
<p>Let's now build the calculator in SAS Intelligent Decisioning, including the operations, the model, and the extra logic.</p>
<h2>Step 3 - Embed the needed logic into the decision to perform the calculator operations</h2>
<p>The diagram below represents the Decision flow for our calculator example. Each node is numbered and followed by a definition.<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/figure16_calculator.png"><img loading="lazy" class="aligncenter size-large wp-image-36342" src="https://blogs.sas.com/content/sgf/files/2021/11/figure16_calculator-1024x640.png" alt="" width="702" height="439" srcset="https://blogs.sas.com/content/sgf/files/2021/11/figure16_calculator-1024x640.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/figure16_calculator-300x188.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/figure16_calculator-768x480.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/figure16_calculator-343x215.png 343w, https://blogs.sas.com/content/sgf/files/2021/11/figure16_calculator.png 1097w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p><strong>0 -</strong> Overall decision flow - <a href="https://github.com/sascommunities/sas-users-blog/blob/master/calculator-regression-model-decision/Calculator%20(1.0).pdf">definition doc found here on GitHub</a><br />
<strong>1 -</strong> Determine if zero is a factor for multiplication or division operations - <a href="https://github.com/sascommunities/sas-users-blog/blob/master/calculator-regression-model-decision/Calculator_Mul_Div_zero(1.0).pdf">definition doc found here on GitHub</a><br />
<strong>2 -</strong> Decision handles value of previous step - set Variable = Decision_Internal_EndProcess = True<br />
<strong>3 -</strong> Process calculations based on operation value - <a href="https://github.com/sascommunities/sas-users-blog/blob/master/calculator-regression-model-decision/Calculator_Operations_Rules(1.0).pdf">definition doc found here on GitHub</a><br />
<strong>4 -</strong> Calculator linear regression model created earlier in the post - <a href="https://github.com/sascommunities/sas-users-blog/blob/master/calculator-regression-model-decision/Linear%20Regression%20(Pipeline%201).zip">model definition file found here on GitHub</a><br />
<strong>5 -</strong> Additional logic to finalize processing on multiplication and division operations - <a href="https://github.com/sascommunities/sas-users-blog/blob/master/calculator-regression-model-decision/Calculator_Process_Outputs(1.0).pdf">definition doc found here on GitHub</a></p>
<h2>Step 4 - Publish the final artifact created as an API service</h2>
<p>After completing all the work on the decision, click on the Publish button and the Calculator is ready to be consumed via an API.</p>
<p>A colleague of mine created a simple web application which calls models using SAS Viya microservice APIs. I'll use this web app to display the results of my calculator. For brevity, I won't cover the details of the app. If you'd like to see how to create a web app using SAS APIs, I recommend the <a href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Build-a-web-application-using/ta-p/762276">Build a web application using SAS Compute Server</a> series on the SAS Communities.</p>
<p>The app allows me to choose my decision flow, add my operands and indicate an operation as seen below.<br />
<a href="https://blogs.sas.com/content/sgf/files/2021/11/figure17_calculator.png"><img loading="lazy" class="aligncenter size-large wp-image-36345" src="https://blogs.sas.com/content/sgf/files/2021/11/figure17_calculator-1024x842.png" alt="" width="702" height="577" srcset="https://blogs.sas.com/content/sgf/files/2021/11/figure17_calculator-1024x842.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/figure17_calculator-300x247.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/figure17_calculator-768x631.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/figure17_calculator-168x137.png 168w, https://blogs.sas.com/content/sgf/files/2021/11/figure17_calculator.png 1100w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>I tested with several operand and operation combinations and they all checked out. It worked!</p>
<h1>Final Thoughts</h1>
<p>I can consider my self-challenge solved. Through this example we accomplished the following:</p>
<ul>
<li>The Calculator API Service can perform the four operations based on a Machine Learning Model.</li>
<li>I created a simple Machine Learning Model to perform the addition of two decimal numbers from a 100 registers data set.</li>
<li>The model and the extra logic needed to perform the operations was developed under the low code / no code paradigm.</li>
<li>I used the visual interface to generate the model and the extra logic, in conjunction with the expression builder, to apply the logarithm and exponential operations.</li>
<li>The overall process has taken no more than a couple of hours.</li>
</ul>
<p>Apart from the usefulness of this API, my principal takeaways of this self-challenge are:</p>
<ul>
<li>In this case, building my data set to obtain the exact behavior I wanted for my model was quite straight-forward.</li>
<li>Building the model through the Graphical User Interface was easy and fast.</li>
<li>Having the capacity to embed the models with extra logic under the low code / no code paradigm provides “supercharged intelligence” to the model</li>
<li>The publishing feature of the whole artifact as an API service is great, providing instant value to the consumers.</li>
<li>SAS Viya is a great platform as it provides all the pieces needed to satisfy your analytical business needs as well as your “curiosity needs”.</li>
</ul>
<p>&nbsp;</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/09/sas-ml-model-intelligent-decisioning-build-calculator/">How I used a SAS ML model and Intelligent Decisioning to build a calculator</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_uNCILGN6O0:YVdmMTpgFWk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_uNCILGN6O0:YVdmMTpgFWk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=_uNCILGN6O0:YVdmMTpgFWk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_uNCILGN6O0:YVdmMTpgFWk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_uNCILGN6O0:YVdmMTpgFWk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=_uNCILGN6O0:YVdmMTpgFWk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_uNCILGN6O0:YVdmMTpgFWk:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_uNCILGN6O0:YVdmMTpgFWk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=_uNCILGN6O0:YVdmMTpgFWk:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/11/09/sas-ml-model-intelligent-decisioning-build-calculator/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/11/additonOp-150x150.png" />
	</item>
		<item>
		<title>SAS Enterprise Session Monitor - Obsessing over Observability</title>
		<link>https://blogs.sas.com/content/sgf/2021/11/04/sas-enterprise-session-monitor/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/11/04/sas-enterprise-session-monitor/#respond</comments>
		
		<dc:creator><![CDATA[Erik Pearsall]]></dc:creator>
		<pubDate>Thu, 04 Nov 2021 13:09:16 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[CAS]]></category>
		<category><![CDATA[CAS Actions]]></category>
		<category><![CDATA[Developers]]></category>
		<category><![CDATA[SAS 9]]></category>
		<category><![CDATA[SAS Enterprise Session Monitor]]></category>
		<category><![CDATA[SAS Viya]]></category>
		<category><![CDATA[SAS workloads]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=36174</guid>

					<description><![CDATA[<p>Think about what a modern implementation of SAS looks like for a customer. Programmers rely on robust environments to run the models and programs that answer business questions. These environments can be different for platforms like SAS® 9 and SAS® Viya®. They can be deployed across distributed servers, either on [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/04/sas-enterprise-session-monitor/">SAS Enterprise Session Monitor - Obsessing over Observability</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Think about what a modern implementation of SAS looks like for a customer. Programmers rely on robust environments to run the models and programs that answer business questions. These environments can be different for platforms like SAS® 9 and SAS® Viya®. They can be deployed across distributed servers, either on premises or using a cloud provider (sometimes both at the same time). These environments could even be set up across geographic regions for programmers across time zones. And we’re just thinking about the SAS servers—not counting data sources and third-party servers. All of these systems have their own suites of monitoring tools, which only show small slices of the big picture. </p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Erik-1.png"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/11/Erik-1.png" alt="" width="915" height="466" class="alignnone size-full wp-image-36177" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Erik-1.png 915w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-1-300x153.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-1-768x391.png 768w" sizes="(max-width: 915px) 100vw, 915px" /></a></p>
<h3>Observing all environments</h3>
<p>SAS Enterprise Session Monitor aims to be the single point of contact for observing distributed systems. It brings unparalleled visibility to understanding environments using detailed system and application-level metrics for every session of SAS that is launched. This goes beyond traditional monitoring and into observability—aggregating, correlating, and analyzing a steady stream of constant data from systems to effectively troubleshoot or debug environments and sessions. Sessions in this case are those that come from SAS 9, SAS Viya, build servers, testing environments, and more. SAS Enterprise Session Monitor receives that data, displays it live in the tool, and stores the data for historical review in an embedded database.</p>
<p>SAS Enterprise Session Monitor is extensible and customizable: administrators can build patterns using regular expressions to track third-party sessions or custom in-house applications. If a process runs on a Windows or Linux server, SAS Enterprise Session Monitor can be configured to record metrics about it.</p>
<h3>What metrics are collected?</h3>
<p>SAS Enterprise Session Monitor collects and stores system metrics and logs, many monitoring tools do. Here is where things begin to get interesting, however: SAS Enterprise Session Monitor collects application-level metrics about SAS user sessions. The size of the SASWORK area is monitored and the amount of space in the CAS_DISK_CACHE. Users of SAS Enterprise Session Monitor are able see within DATA and PROC steps as code executes within SAS 9 or SAS Compute Server sessions. SAS Viya users can see the CAS actions that execute within their CAS sessions.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Erik-2.png"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/11/Erik-2-1024x569.png" alt="" width="702" height="390" class="alignnone size-large wp-image-36183" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Erik-2-1024x569.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-2-300x167.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-2-768x427.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-2.png 1073w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>This information is presented in the form of spans which appear on a time-series graph along with session information such as CPU usage, memory usage and disk usage. This user activity is tracked for all user sessions, across all platforms. This code-level analysis can help to understand which SAS Procedures are used, which (and how frequently) datasets are opened, and which users are using the environments at different times.</p>
<h3>Grand central admin-station</h3>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Erik-3.png"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/11/Erik-3-1024x441.png" alt="" width="702" height="302" class="alignnone size-large wp-image-36186" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Erik-3-1024x441.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-3-300x129.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-3-768x331.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-3.png 1351w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>Administrators use SAS Enterprise Session Monitor to make sure their environments are stable and performant. Historical data can be used to profile workloads, charge back departments or help promote jobs between development, testing and production environments. Critical system resources are tracked to better understand when peak usage time is and to understand where resource constraints occur. This stored historical data can also be used for troubleshooting purposes, and all sessions and jobs can be searched for error events to help in problem analysis. Profiles of scheduled batch jobs can be graphed to see when large numbers of sequential programs could be redesigned to run in parallel. SAS Enterprise Session Monitor knows when distributed workloads should be linked together – in a SAS Grid or MPP CAS deployment.</p>
<h3>Lower total cost of ownership</h3>
<p>Administrators can use SAS Enterprise Session Monitor to accurately right-size their infrastructure with all the metrics collected — whether that is in the cloud or on premises. Accurate user counts and licensing can be determined for concurrent users in all distributed environments. And with accurate information coming in from distributed environments and multiple nodes, potential problems can be identified, and administrators can accelerate time to resolution and reduce system downtime on production or business-critical systems. </p>
<p>A drag-and-drop interface also allows for workloads from different teams to generate cost allocation rules so that costs can be charged back to departments depending on their usage of system resources. This allows for accurate tracking of cooperative resource sharing.</p>
<h3>Empowering development teams</h3>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Erik-4.png"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/11/Erik-4-1024x506.png" alt="" width="702" height="347" class="alignnone size-large wp-image-36189" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Erik-4-1024x506.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-4-300x148.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-4-768x379.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-4-164x82.png 164w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-4.png 1116w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>Developers (data scientists, analysts or programmers) use SAS Enterprise Session Monitor in real time to monitor or view progress of their code as it runs. This improves the developer experience and closes the feedback loop as they can see issues before something is promoted to production. Developers can use it to prioritize jobs and have insight into what is happening during their program execution.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Erik-5.png"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/11/Erik-5-1024x479.png" alt="" width="702" height="328" class="alignnone size-large wp-image-36192" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Erik-5-1024x479.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-5-300x140.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-5-768x359.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-5.png 1338w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>This empowers individual programmers, as well as teams of developers: teams can be configured to have access to their other team members’ sessions in SAS Enterprise Session Monitor. Privileged users can also be configured to allow team leads or power users to terminate sessions and view SAS program logs from the SAS Enterprise Session Monitor interface in a secure and audited way. </p>
<h3>Other tidbits</h3>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Erik-6.png"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/11/Erik-6-1024x432.png" alt="" width="702" height="296" class="alignnone size-large wp-image-36195" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Erik-6-1024x432.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-6-300x127.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-6-768x324.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-6.png 1459w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>I mentioned how SAS Enterprise Session Monitor can analyze batch job flows, visualizing them into graphs that display total runtime and dependencies. Taking this a step further, the batch job flows can be viewed through Relative Comparisons — a feature where two defined time spans can be compared. Simply put, this means that one set of scheduled work can be compared to a previous run. This can give detailed information when evaluating whether to change a program or model, or when performing root-cause analysis of issues that impact the runtime of the scheduled work.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/11/Erik-7.png"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/11/Erik-7-1024x451.png" alt="" width="702" height="309" class="alignnone size-large wp-image-36198" srcset="https://blogs.sas.com/content/sgf/files/2021/11/Erik-7-1024x451.png 1024w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-7-300x132.png 300w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-7-768x338.png 768w, https://blogs.sas.com/content/sgf/files/2021/11/Erik-7.png 1433w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>Lastly, developers can use real-time custom chart annotations that show up on the time-series graph. The %esmtag statement generates these annotations and can be used much like %put statements. These can be used as status checkpoints or observation counts, providing feedback in real time as the developer watches the program execute. These annotations are searchable in SAS Enterprise Session Monitor.</p>
<h3>Summary</h3>
<p>I hope you can feel my excitement about this tool and are able to see a few reasons to check this offering out — the potential for what can be monitored is almost endless. Here’s a quick recap:</p>
<ul>
•	Enterprise Session Monitor provides visibility into many different types of SAS workloads. Servers and microservices across multiple SAS 9 and SAS Viya environments can be monitored in one place. Even third-party tools and data sources can be monitored with a little customization.</p>
<p>•	Developers use it to close the feedback loop when developing new SAS programs.</p>
<p>•	Administrators use it to solve platform issues—through session management, live data and historical data about SAS processes and system resources.
</ul>
<h3>Additional resources</h3>
<p><a href="https://documentation.sas.com/doc/en/esmoncdc/3.5/esmonwlcm/home.htm?fromDefault=">SAS Enterprise Session Monitor documentation</a></p>
<p><a href="https://support.sas.com/edu/schedules.html?id=23777&amp;ctry=US">Configuration and Usage of SAS Enterprise Session Monitor</a> </p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/04/sas-enterprise-session-monitor/">SAS Enterprise Session Monitor - Obsessing over Observability</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=mMNnqqurm3A:GnAiJ8CHVQk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=mMNnqqurm3A:GnAiJ8CHVQk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=mMNnqqurm3A:GnAiJ8CHVQk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=mMNnqqurm3A:GnAiJ8CHVQk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=mMNnqqurm3A:GnAiJ8CHVQk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=mMNnqqurm3A:GnAiJ8CHVQk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=mMNnqqurm3A:GnAiJ8CHVQk:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=mMNnqqurm3A:GnAiJ8CHVQk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=mMNnqqurm3A:GnAiJ8CHVQk:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/11/04/sas-enterprise-session-monitor/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/11/Erik-1-150x150.png" />
	</item>
		<item>
		<title>Creating Simulated Data Sets</title>
		<link>https://blogs.sas.com/content/sgf/2021/11/02/creating-simulated-data-sets/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/11/02/creating-simulated-data-sets/#respond</comments>
		
		<dc:creator><![CDATA[Ron Cody]]></dc:creator>
		<pubDate>Tue, 02 Nov 2021 13:33:29 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[CALL STREAMINIT]]></category>
		<category><![CDATA[RAND function]]></category>
		<category><![CDATA[simulated data]]></category>
		<category><![CDATA[simulation]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=36096</guid>

					<description><![CDATA[<p>There are times when it is useful to simulate data. One of the reasons I use simulated data sets is to demonstrate statistical techniques such as multiple or logistic regression. By using SAS random functions and some DATA step logic, you can create variables that follow certain distributions or are [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/02/creating-simulated-data-sets/">Creating Simulated Data Sets</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>There are times when it is useful to simulate data. One of the reasons I use simulated data sets is to demonstrate statistical techniques such as multiple or logistic regression. By using SAS random functions and some DATA step logic, you can create variables that follow certain distributions or are correlated with other variables. You might decide to simulate a drug study where the drug group has a higher or lower mean than a placebo group.</p>
<p>Because most programs that create simulated data use random numbers, let's start off by discussing the RAND function. This function can generate random numbers that follow distributions such as uniform, normal, Bernoulli, as well as dozens of other distributions. Veteran SAS programmers might be more familiar with some of the older random number functions such as RANUNI and RANNOR. RANUNI was used to generate uniform random numbers (numbers between 0 and 1) and RANNOR generated random numbers from a normal distribution. The RAND function has replaced <strong>all</strong> of the older functions and has a number of advantages over the older functions.</p>
<p>The first argument of the RAND function is the name of the distribution that you want to use, such as Uniform, Normal, or Bernoulli. For some of the distributions, such as Normal, you can supply parameters such as the mean and standard deviation. Here are some examples:</p>
<table>
<tbody>
<tr>
<td width="150"><strong>Function</strong></td>
<td width="474"><strong>Description</strong></td>
</tr>
<tr>
<td width="150">rand('Uniform')</td>
<td width="474">Generates uniform random numbers (between 0 and 1)</td>
</tr>
<tr>
<td width="150">rand('Normal',100,20)</td>
<td width="474">Generates values from a normal distribution with a mean of 100 and a standard deviation of 20</td>
</tr>
<tr>
<td width="150">rand('Bernoulli',.4)</td>
<td width="474">Generates a 0 or 1 with a probability of a 1 equal to .4</td>
</tr>
<tr>
<td width="150">rand('Binomial',.2,5)</td>
<td width="474">Generates random numbers that represent the number of successes in a sample of size 5 with the probability of success equal to .2</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Important Note: if you want a <strong>reproducible</strong> series of random numbers using the RAND function, you must seed it by a call to STREAMINIT (with a positive integer argument) prior to its use. For example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">       <span style="color: #0000ff;">call</span> streaminit<span style="color: #66cc66;">&#40;</span><span style="color: #2e8b57; font-weight: bold;">132435</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>To clarify the note above, here are two programs that use the RAND function—one with, and one without the call to Streaminit.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"> <span style="color: #000080; font-weight: bold;">data</span> Without;
   <span style="color: #0000ff;">do</span> i = <span style="color: #2e8b57; font-weight: bold;">1</span> to <span style="color: #2e8b57; font-weight: bold;">5</span>;
      <span style="color: #0000ff;">x</span> = rand<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'Uniform'</span><span style="color: #66cc66;">&#41;</span>;
      <span style="color: #0000ff;">output</span>;
   <span style="color: #0000ff;">end</span>;   <span style="color: #0000ff;">drop</span> i;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>Here is the output from running this program twice.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_1.jpg"><img loading="lazy" class="alignnone wp-image-36117 size-full" src="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_1.jpg" alt="" width="1299" height="353" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_1.jpg 1299w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_1-300x82.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_1-1024x278.jpg 1024w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_1-768x209.jpg 768w" sizes="(max-width: 1299px) 100vw, 1299px" /></a></p>
<p>Notice that the values of x are different in each run. Now let's run the same program with CALL STREAMINIT included. Here is the program.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">data</span> With;
   <span style="color: #0000ff;">call</span> streaminit<span style="color: #66cc66;">&#40;</span><span style="color: #2e8b57; font-weight: bold;">13579</span><span style="color: #66cc66;">&#41;</span>;
   <span style="color: #0000ff;">do</span> i = <span style="color: #2e8b57; font-weight: bold;">1</span> to <span style="color: #2e8b57; font-weight: bold;">5</span>;
      <span style="color: #0000ff;">x</span> = rand<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'Uniform'</span><span style="color: #66cc66;">&#41;</span>;
      <span style="color: #0000ff;">output</span>;
   <span style="color: #0000ff;">end</span>;
   <span style="color: #0000ff;">drop</span> i;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>And here are the output listings from running this program twice.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_2.jpg"><img loading="lazy" class="alignnone wp-image-36120 size-full" src="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_2.jpg" alt="" width="1183" height="358" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_2.jpg 1183w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_2-300x91.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_2-1024x310.jpg 1024w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_2-768x232.jpg 768w" sizes="(max-width: 1183px) 100vw, 1183px" /></a></p>
<p>Adding CALL STREAMINIT creates the <strong>same</strong> sequence of random numbers each time the program is run. This is useful if you are generating groups for a drug study and want to be able to re-create the random sequences when it comes time to break the blind and analyze the results. Another reason I sometimes want to generate a repeatable sequence of random numbers is for problem sets included in many of my books—I want the reader to get exactly the same results as I did.</p>
<p>Let's switch topics and see how to write a program where you want to simulate flipping a coin. The program below uses a popular method, but not it is not as elegant as the next program I'm going to show you.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #006400; font-style: italic;">*Old fashioned way to generate &quot;random&quot; events;</span>
<span style="color: #000080; font-weight: bold;">data</span> Toss;
   <span style="color: #0000ff;">do</span> <span style="color: #0000ff;">n</span> = <span style="color: #2e8b57; font-weight: bold;">1</span> to <span style="color: #2e8b57; font-weight: bold;">10</span>;
      <span style="color: #0000ff;">if</span> rand<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'uniform'</span><span style="color: #66cc66;">&#41;</span> lt .5 <span style="color: #0000ff;">then</span> Result = <span style="color: #a020f0;">'Tails'</span>;
      <span style="color: #0000ff;">else</span> Result = <span style="color: #a020f0;">'Heads'</span>;
      <span style="color: #0000ff;">output</span>;
   <span style="color: #0000ff;">end</span>;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>In the long run, half of the uniform random numbers will be less than .5, and the proportion of heads and tails will be approximately .5. Here is a listing of data set Toss.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_3.jpg"><img loading="lazy" class="alignnone size-medium wp-image-36099" src="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_3-220x300.jpg" alt="" width="220" height="300" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_3-220x300.jpg 220w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_3.jpg 455w" sizes="(max-width: 220px) 100vw, 220px" /></a></p>
<p>A more sophisticated approach takes advantage of the RAND function's ability to generate random number from multiple distributions. A Bernoulli distribution is similar to a coin toss where you can adjust the probability of a 1 or 0 by including a second parameter to the function. The Toss2 program, shown below, does just that.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #006400; font-style: italic;">*More sophisticated program;</span>
proc <span style="color: #0000ff;">format</span>;
   value Heads_Tails <span style="color: #2e8b57; font-weight: bold;">0</span>=<span style="color: #a020f0;">&quot;Heads&quot;</span> <span style="color: #2e8b57; font-weight: bold;">1</span>=<span style="color: #a020f0;">&quot;Tails&quot;</span>;
<span style="color: #000080; font-weight: bold;">run</span>;
&nbsp;
<span style="color: #000080; font-weight: bold;">data</span> Toss2;
   <span style="color: #0000ff;">do</span> <span style="color: #0000ff;">n</span> = <span style="color: #2e8b57; font-weight: bold;">1</span> to <span style="color: #2e8b57; font-weight: bold;">10</span>;
      Results = rand<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'Bernoulli'</span>,.5<span style="color: #66cc66;">&#41;</span>;
      <span style="color: #0000ff;">format</span> Results Heads_Tails.;
      <span style="color: #0000ff;">output</span>;
   <span style="color: #0000ff;">end</span>;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>The format Heads_Tails substitutes the labels "Heads" and "Tails" for values of 0 and 1, respectively. Here is a listing of data set Toss2.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_4.jpg"><img loading="lazy" class="alignnone size-medium wp-image-36102" src="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_4-221x300.jpg" alt="" width="221" height="300" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_4-221x300.jpg 221w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_4.jpg 462w" sizes="(max-width: 221px) 100vw, 221px" /></a></p>
<p>The final discussion of this blog, concerns generating random values of two or more variables that are correlated. The example that follows generates x-y pairs that are correlated.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #006400; font-style: italic;">*Creating correlated x-y pairs;</span>
<span style="color: #000080; font-weight: bold;">data</span> Corr;
   <span style="color: #0000ff;">do</span> i = <span style="color: #2e8b57; font-weight: bold;">1</span> to <span style="color: #2e8b57; font-weight: bold;">1000</span>;
      <span style="color: #0000ff;">x</span> = rand<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'normal'</span>,<span style="color: #2e8b57; font-weight: bold;">100</span>,<span style="color: #2e8b57; font-weight: bold;">10</span><span style="color: #66cc66;">&#41;</span>;
      y = .5<span style="color: #006400; font-style: italic;">*x + rand('Normal',50,10);</span>
      <span style="color: #0000ff;">output</span>;
   <span style="color: #0000ff;">end</span>;
   <span style="color: #0000ff;">drop</span> i;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>By including a proportion of the x-value when creating the y-value, the x- and y-values will be correlated. Shown below is the output from PROC CORR, showing that x and y are correlated (r = .45586).</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_5.jpg"><img loading="lazy" class="alignnone wp-image-36105 size-large" src="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_5-1024x702.jpg" alt="" width="702" height="481" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_5-1024x702.jpg 1024w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_5-300x206.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_5-768x526.jpg 768w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_5.jpg 1065w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>I used a SAS Studio task to create the scatterplot shown next.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_6.jpg"><img loading="lazy" class="alignnone wp-image-36108 size-large" src="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_6-1024x767.jpg" alt="" width="702" height="526" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_6-1024x767.jpg 1024w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_6-300x225.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_6-768x575.jpg 768w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_6.jpg 1168w" sizes="(max-width: 702px) 100vw, 702px" /></a></p>
<p>You can increase or decrease the correlation by increasing the proportion of x used to create y. For example, you could use y = .8*x + rand('Normal',20,10); to create x-y pairs with a higher correlation.</p>
<p>You can see more examples of the RAND function in my book, <a href="https://sasinstitute.redshelf.com/book/1878411/sas-functions-by-example-second-edition-1878411-9781607643647-ron-cody-edd"><em>SAS Functions by Example</em>, Second Edition,</a> available as an e-book from RedShelf or in print form from Amazon.</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_7.png"><img loading="lazy" class="alignnone size-medium wp-image-36111" src="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_7-279x300.png" alt="" width="279" height="300" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_7-279x300.png 279w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_7.png 719w" sizes="(max-width: 279px) 100vw, 279px" /></a></p>
<p>To learn more about how to use SAS Studio as part of OnDemand for Academics, to write SAS programs, or to use SAS Studio tasks, please take a look at my new book: <a href="https://sasinstitute.redshelf.com/book/1878370/getting-started-with-sas-programming-1878370-9781953329189-ron-cody"><em>Getting Started with SAS Programing: Using SAS Studio in the Cloud</em> </a>(available in e-book from RedShelf or in a paper version from Amazon).</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_8.png"><img loading="lazy" class="alignnone size-medium wp-image-36114" src="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_8-255x300.png" alt="" width="255" height="300" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Simulation_8-255x300.png 255w, https://blogs.sas.com/content/sgf/files/2021/10/Simulation_8.png 752w" sizes="(max-width: 255px) 100vw, 255px" /></a></p>
<p>I hope you enjoyed reading this blog and, as usual, I invite comments and/or questions.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/11/02/creating-simulated-data-sets/">Creating Simulated Data Sets</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=-kWjmXnLrOI:UqeLQW9JqiU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=-kWjmXnLrOI:UqeLQW9JqiU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=-kWjmXnLrOI:UqeLQW9JqiU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=-kWjmXnLrOI:UqeLQW9JqiU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=-kWjmXnLrOI:UqeLQW9JqiU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=-kWjmXnLrOI:UqeLQW9JqiU:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=-kWjmXnLrOI:UqeLQW9JqiU:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=-kWjmXnLrOI:UqeLQW9JqiU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=-kWjmXnLrOI:UqeLQW9JqiU:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/11/02/creating-simulated-data-sets/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/10/42-15326326-150x150.jpg" />
	</item>
		<item>
		<title>Additional statistical capabilities in the containerized deployment of SAS Analytics Pro</title>
		<link>https://blogs.sas.com/content/sgf/2021/10/29/sas-analytics-pro-capabilities/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/10/29/sas-analytics-pro-capabilities/#respond</comments>
		
		<dc:creator><![CDATA[Mike Gilliland]]></dc:creator>
		<pubDate>Fri, 29 Oct 2021 17:26:57 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[base sas]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[SAS Analytics Pro]]></category>
		<category><![CDATA[SAS Viya]]></category>
		<category><![CDATA[SAS/ACCESS]]></category>
		<category><![CDATA[sas/graph]]></category>
		<category><![CDATA[SAS/Stat]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=36153</guid>

					<description><![CDATA[<p>SAS Analytics Pro consists of three core elements of the SAS system: Base SAS®, SAS/GRAPH® and SAS/STAT®. The containerized deployment option adds the full selection of SAS/ACCESS engines making it even easier to work with data from virtually any source.</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/29/sas-analytics-pro-capabilities/">Additional statistical capabilities in the containerized deployment of SAS Analytics Pro</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In a <a href="https://blogs.sas.com/content/sgf/2021/09/10/sas-analytics-pro-cloud-native-deployment/">September 10 post</a> on the SAS Users blog, we announced that <a href="https://www.sas.com/en_us/software/analytics-pro.html">SAS Analytics Pro</a> is now available for on-site or containerized cloud-native deployment. For our thousands of SAS Analytics Pro customers, this provides an entry point into <a href="https://www.sas.com/en_us/software/viya.html">SAS Viya</a>.</p>
<p>SAS Analytics Pro consists of three core elements of the SAS system: <a href="https://www.sas.com/en_us/software/base-sas.html">Base SAS®</a>, <a href="https://support.sas.com/en/software/sasgraph-support.html">SAS/GRAPH®</a> and <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/allprodsproc/p1o1v16by0iotvn10m0jzzv9i3y8.htm#p1mdfdo2rlj2njn1jje0jur16v3ya">SAS/STAT®</a>. The containerized deployment option adds the full selection of <a href="https://www.sas.com/en_us/software/access.html">SAS/ACCESS</a> engines making it even easier to work with data from virtually any source.</p>
<p>Even better, the containerized deployment option now adds new statistical capabilities that are not available in SAS/STAT on SAS9. Thanks to SAS Viya’s continuous delivery approach, we are able to provide this additional functionality so soon after the initial release.</p>
<p>Below are highlights of these additional capabilities (you can find more details by following the links):</p>
<h2>Causal Inference Procedures</h2>
<ul>
<li>Carry out causal mediation analysis of <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_causalmed_examples05.htm">time-to-event data</a> (either by Cox proportion hazard model or accelerated failure time model) in <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_causalmed_toc.htm?homeOnFail=">PROC CAUSALMED</a>.</li>
<li>Use new causal effect identification <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_causalgraph_syntax01.htm#statug.causalgraph.cagrmethod">methods</a>, <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_causalgraph_syntax01.htm#statug.causalgraph.cagrinmodel">import</a> and <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_causalgraph_syntax01.htm#statug.causalgraph.cagroutmodel">export</a> models in <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_causalgraph_toc.htm">PROC CAUSALGRAPH</a>.</li>
<li>PROC CAUSALGRAPH also supports expanded grammar options and the <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_causalgraph_syntax09.htm">PATHDIAGRAM</a> statement outputs graphical path diagrams.</li>
</ul>
<h2>Bayesian Analysis Procedures</h2>
<ul>
<li>Model <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_bglimm_syntax06.htm#statug.bglimm.model_dist">multinomial</a> data with cumulative probit, cumulative logit, generalized link, or other link functions in <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_bglimm_toc.htm">PROC BGLIMM</a>.</li>
<li>Specify fixed <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_bglimm_syntax06.htm#statug.bglimm.model_scale">scale</a> values in a generalized linear mixed-effects model, and use an improved <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_mcmc_syntax08.htm">CMPTMODEL</a> statement in <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_mcmc_toc.htm">PROC MCMC</a> and <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_nlmixed_toc.htm">PROC NLMIXED</a> to fit compartment models.</li>
</ul>
<h2>Survey Procedures</h2>
<ul>
<li>Compute new design-adjusted <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_surveyfreq_details41.htm#statug.surveyfreq.sfreqclac">confidence limits</a> for proportions in <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_surveyfreq_toc.htm">PROC SURVEYFREQ</a>.</li>
<li>Use new <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_surveyselect_syntax01.htm#statug.surveyselect.selectgroups">random assignments</a> options in <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_surveyselect_toc.htm">PROC SURVEYSELECT</a>.</li>
<li>Request new confidence limits, such as the <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_freq_syntax08.htm#statug.freq.freqbac">Agresti-Coul</a> limits in <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_freq_toc.htm">PROC FREQ</a>.</li>
</ul>
<h3>Additional Capabilities:</h3>
<ul>
<li>The new <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_glimmix_syntax15.htm">MARGINS</a> statement in <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_glimmix_toc.htm">PROC GLIMMIX</a> computes predictive margins of fixed effects.</li>
<li>The <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_qreg_syntax08.htm#statug.qreg.quantregfmodelquantile">Fast Quantile Profess Regression</a> solver improves performance in <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/statug/statug_qreg_toc.htm">PROC QUANTREG</a>. For complete information on all new statistical features that the containerized Analytics Pro provides, see the <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/allprodsproc/p1o1v16by0iotvn10m0jzzv9i3y8.htm#p1mdfdo2rlj2njn1jje0jur16v3ya">SAS/STAT documentation</a>.</li>
</ul>
<p>For those SAS customers already on SAS Viya, or those considering the move, SAS Analytics Pro provides one more example of the new powers you will enjoy!</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/29/sas-analytics-pro-capabilities/">Additional statistical capabilities in the containerized deployment of SAS Analytics Pro</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_ibpo2AHfE8:RNqbhokKRsQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_ibpo2AHfE8:RNqbhokKRsQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=_ibpo2AHfE8:RNqbhokKRsQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_ibpo2AHfE8:RNqbhokKRsQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_ibpo2AHfE8:RNqbhokKRsQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=_ibpo2AHfE8:RNqbhokKRsQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_ibpo2AHfE8:RNqbhokKRsQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=_ibpo2AHfE8:RNqbhokKRsQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=_ibpo2AHfE8:RNqbhokKRsQ:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/10/29/sas-analytics-pro-capabilities/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/10/SASAnalyticsPro-150x150.png" />
	</item>
		<item>
		<title>Creating a React web app using SAS Viya</title>
		<link>https://blogs.sas.com/content/sgf/2021/10/28/creating-a-react-web-app-using-sas-viya/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/10/28/creating-a-react-web-app-using-sas-viya/#respond</comments>
		
		<dc:creator><![CDATA[Xavier Bizoux]]></dc:creator>
		<pubDate>Thu, 28 Oct 2021 12:09:06 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[CAS]]></category>
		<category><![CDATA[Compute Server]]></category>
		<category><![CDATA[Developers]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Jobs]]></category>
		<category><![CDATA[MAS]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[SAS Viya]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=35646</guid>

					<description><![CDATA[<p>From articles I've read on the web, it is clear that data is gold in the twenty-first century. Loading, enriching, manipulating and analyzing data is something in which SAS excels. Based on questions from colleagues and customers, it is clear end-users are willing to display data handled by SAS outside [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/28/creating-a-react-web-app-using-sas-viya/">Creating a React web app using SAS Viya</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>From articles I've read on the web, it is clear that data is gold in the twenty-first century. Loading, enriching, manipulating and analyzing data is something in which SAS excels. Based on questions from colleagues and customers, it is clear end-users are willing to display data handled by SAS outside of the user interfaces bundled with the SAS software.</p>
<p>I recently completed a series of articles on the <a href="https://communities.sas.com/t5/SAS-Communities-Library/tkb-p/library">SAS Community library</a> where I shed some light on different techniques for feeding web applications with SAS data stored in SAS Viya environment.  The series includes a discussion of options for extracting data, building a React application, how to build web applications using SAS Viya, SAS Cloud Analytic Service (CAS), SAS Compute Server, and SAS Micro Analytic Service (MAS).</p>
<p>I demonstrate the functionality and discuss project details in the video <a href="https://www.youtube.com/watch?v=suA9W5mZHb0">Develop Web Application to Extract SAS Data</a>, found on the <a href="https://www.youtube.com/c/sasusers">SAS Users YouTube Channel</a>.</p>
<p>I'm tying everything together in this post as a reference point. I'll provide a link to each article along with a brief description. The Community articles have all the detailed steps for developing the application. I'm excited bring you this information, so let's get started.</p>
<h3>Part 1 - Develop web applications series: Options for extracting data</h3>
<p><a href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Options-for-extracting-data/ta-p/732161">In this first article</a>, I explain when to use SAS Micro Analytic Service, SAS Viya Jobs, SAS Cloud Analytic Service, and SAS Compute Server.</p>
<h3>Part 2 - Develop web applications series: Creating the React based application</h3>
<p>To demonstrate the different options, <a href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Creating-the-React-based/ta-p/741837">in the second article</a>, I create a simple web application using <a href="https://reactjs.org/">React JavaScript library</a>. The application also handles authentication against SAS Viya. The application is structured in such a way to avoid redundant code and each component has a well-defined role. From here, we can build the different pages to access CAS, MAS, Compute Server or SAS Viya Jobs.</p>
<p>The image below offers a view of the application which starts in Part 2 and continues throughout the series..</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/MicrosoftTeams-image.png"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/10/MicrosoftTeams-image.png" alt="" width="961" height="325" class="aligncenter size-full wp-image-35919" srcset="https://blogs.sas.com/content/sgf/files/2021/10/MicrosoftTeams-image.png 961w, https://blogs.sas.com/content/sgf/files/2021/10/MicrosoftTeams-image-300x101.png 300w, https://blogs.sas.com/content/sgf/files/2021/10/MicrosoftTeams-image-768x260.png 768w" sizes="(max-width: 961px) 100vw, 961px" /></a></p>
<h3>Part 3 - Develop web applications series: Build a web application using SAS Viya Jobs</h3>
<p><a href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Build-a-web-application-using/ta-p/747713">In this article</a>, I drive you through the steps to retrieve data from the SAS environment using SAS Viya Jobs. We build out the Jobs tab and on the page, display two dropdown boxes to select a library and table. The final piece is a submit button to retrieve the data to populate a table.</p>
<h3>Part 4 - Develop web applications series: Build a web application using SAS Cloud Analytic Service</h3>
<p><a href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Build-a-web-application-using/ta-p/754290">In article number 4</a>, we go through the steps to build a page similar to the one in the previous article, but this time the data comes directly from the SAS Cloud Analytic Service (CAS). We reuse the application structure which was created in <a href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Creating-the-React-based/ta-p/741837" target="_blank" rel="noopener noreferrer">Part 2</a>. We focus on the CAS tab. As for the SAS Viya Jobs, we display two dropdown boxes to select a library and table. We finish again with a submit button to retrieve the data to populate a table.</p>
<h3>Part 5 - Develop web applications series: Build a web application using SAS Compute Server</h3>
<p><a href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Build-a-web-application-using/ta-p/762276">In the next article</a>, we go through the steps to build a page similar to the ones from previous articles, but this time the data comes directly from the SAS Compute Server. We reuse the application structure created in this <a title="Develop web applications series: Creating the React based application" href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Creating-the-React-based/ta-p/741837" target="_blank" rel="noopener noreferrer">Part 2</a> article. The remainder of the article focuses on the Compute tab. As for the CAS content, we display two dropdown boxes to select a library and table. Finishing off again with the submit button to retrieve the data to populate a table.</p>
<h3>Part 6 - Develop web applications series: Build a web application using SAS Micro Analytic Service</h3>
<p><a href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Build-a-web-application-using/ta-p/769796">For the final article</a>, you discover how to build a page to access data from the SAS Micro Analytic Service. We reuse the same basic web application built in <a href="https://communities.sas.com/t5/SAS-Communities-Library/Develop-web-applications-series-Creating-the-React-based/ta-p/741837" target="_blank" rel="noopener noreferrer">Part 2.</a> However, this time it will require a bit more preparation work as the SAS Micro Analytic Service (MAS) is designed for model scoring.</p>
<h3>Bonus Material - SAS Authentication for ReactJS based applications</h3>
<p><a href="https://communities.sas.com/t5/SAS-Communities-Library/SAS-Authentication-for-ReactJS-based-applications/ta-p/776687">In this addendum to the series</a>, I outline the authorization code OAuth flow. This is the recommended means of authenticating to SAS Viya and I provide technical background and detailed code.</p>
<h2>Conclusion</h2>
<p>If you followed along with the different articles in this series, you should now have a fully functional web application for accessing different data source types from SAS Viya. This application is not for use as-is in production. You should, for example add functionality to handle token expiration. You can of course tweak the interface to get the look and feel you prefer.</p>
<p>See all of my SAS Communities articles <a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/114048" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/28/creating-a-react-web-app-using-sas-viya/">Creating a React web app using SAS Viya</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=2NWTdRz4vpQ:OlgjHsAVtXQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=2NWTdRz4vpQ:OlgjHsAVtXQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=2NWTdRz4vpQ:OlgjHsAVtXQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=2NWTdRz4vpQ:OlgjHsAVtXQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=2NWTdRz4vpQ:OlgjHsAVtXQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=2NWTdRz4vpQ:OlgjHsAVtXQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=2NWTdRz4vpQ:OlgjHsAVtXQ:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=2NWTdRz4vpQ:OlgjHsAVtXQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=2NWTdRz4vpQ:OlgjHsAVtXQ:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/10/28/creating-a-react-web-app-using-sas-viya/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/10/sasAndReact-150x150.png" />
	</item>
		<item>
		<title>Debugging a stored-process problem</title>
		<link>https://blogs.sas.com/content/sgf/2021/10/20/debugging-a-stored-process-problem/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/10/20/debugging-a-stored-process-problem/#respond</comments>
		
		<dc:creator><![CDATA[Kim Wilson]]></dc:creator>
		<pubDate>Wed, 20 Oct 2021 13:52:59 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[Problem Solvers]]></category>
		<category><![CDATA[SAS Stored Process]]></category>
		<category><![CDATA[stored processes]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=35955</guid>

					<description><![CDATA[<p>Have you ever submitted a stored process, and instead of the expected output, you saw errors or no output at all? Depending on how you submit the stored process, various logs are available to assist you with debugging.</p>
<p>This article provides guidance for understanding which situations call for which logs, where to find each log, and what you should look for in each log. </p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/20/debugging-a-stored-process-problem/">Debugging a stored-process problem</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div id="attachment_15148" style="width: 310px" class="wp-caption alignright"><img aria-describedby="caption-attachment-15148" loading="lazy" class="size-medium wp-image-15148" src="https://blogs.sas.com/content/sgf/files/2017/05/ProblemSolvers_Graphic-300x300.jpg" alt="" width="300" height="300" srcset="https://blogs.sas.com/content/sgf/files/2017/05/ProblemSolvers_Graphic-300x300.jpg 300w, https://blogs.sas.com/content/sgf/files/2017/05/ProblemSolvers_Graphic-150x150.jpg 150w, https://blogs.sas.com/content/sgf/files/2017/05/ProblemSolvers_Graphic.jpg 400w" sizes="(max-width: 300px) 100vw, 300px" /><p id="caption-attachment-15148" class="wp-caption-text">View more <a href="https://blogs.sas.com/content/tag/problem-solvers/">Problem Solvers posts</a></p></div>
<p><em>This article is co-authored with my colleague Russ Tyndall, a Senior Principal Technical Support Analyst at SAS.</em></p>
<p>As defined in the SAS<sup>®</sup> 9.4 Stored Processes: Developer's Guide, Third Edition, a stored process "is a SAS program that is stored on a server and defined in metadata, and which can be executed as requested by client applications." One of the benefits of using stored processes is that client applications always have the latest version of the code. In addition, stored processes provide enhanced security and application integrity.</p>
<p>Have you ever submitted a stored process, and instead of the expected output, you saw errors or no output at all? Depending on how you submit the stored process, various logs are available to assist you with debugging.</p>
<p>This article provides guidance for understanding which situations call for which logs, where to find each log, and what you should look for in each log. The article uses two clients as examples: SAS<sup>®</sup> Enterprise Guide<sup>®</sup> and the SAS<sup>®</sup> 9.4 Stored Process Web Application.</p>
<p>The article is divided into two sections:</p>
<ul>
<li>Frequently Used Logs</li>
<li>Infrequently Used Logs</li>
</ul>
<h1 style="color: dodgerblue;">Frequently Used Logs</h1>
<p>The logs that are described in this section are the most prevalent logs that you request when a stored process does not execute properly or when there seems to be a problem with the stored-process server.</p>
<h2 style="color: dodgerblue;">SAS<sup>®</sup> Object Spawner log</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>The SAS Object Spawner log records anytime that the spawner tries to start or stop a stored-process server, a workspace server, or a pooled workspace server. It also records when a request is redirected to a running stored-process server or a pooled workspace server or to a SAS® Grid Manager server.</p>
<p>The syntax for this log's name is ObjectSpawner_<em>yyyy-mm-dd_machine-name_process-ID</em>.log.</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>The default locations for the object-spawner log are as follows:</p>
<ul>
<li><strong>Microsoft Windows operating environments: <tt><em>SAS-configuration-directory</em>\Lev1\ObjectSpawner\Logs</tt></strong></li>
<li><strong>UNIX operating environments: <tt><em>SAS-configuration-directory</em>/Lev1/ObjectSpawner/Logs</tt></strong></li>
</ul>
<p>If the logs are not in the directories that are listed above, you can check the logconfig.xml file that resides in the <tt><strong><em>SAS-configuration-directory</em>\Lev1\ObjectSpawner\</strong></tt> directory. That file contains a parameter called <tt><strong><em>FileNamePattern</em></strong></tt> that determines the location of the object-spawner log, as shown in this example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">&nbsp;</pre></td></tr></table></div>

<h3 style="color: dodgerblue;">Why</h3>
<p>Here are some reasons why you should check the object-spawner log:</p>
<ol>
<li>Performance problems occur within stored processes.</li>
<li>Servers do not start or servers stop working. The stored process server, the workspace server, and the pooled workspace server are all started by the object spawner.</li>
<li>Running a stored process returns no results and no errors.</li>
<li>Users do not have permission to start the server or do not have ReadMetadata permission on their application server context (for example, the SASApp application server).</li>
<li>The connecting user has to wait longer than the availability time-out of 60 seconds, and the stored process fails.</li>
<li>A server is not available on which to run a stored process.</li>
</ol>
<p>The following error is an example of one that you might find in this log:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">The launch of the server process failed due to a problem with the processing of the SAS logging facility configuration <span style="color: #0000ff;">file</span> <span style="color: #66cc66;">&#40;</span>LOGCONFIGLOC<span style="color: #66cc66;">&#41;</span>.</pre></td></tr></table></div>

<p>This error might occur because the file that is specified for the -LOGCONFIGLOC option cannot be processed. The option either is invalid or it cannot be accessed.</p>
<p>For more examples of errors that you might see in the object-spawner log, see the section <a href="https://go.documentation.sas.com/doc/en/bicdc/9.4/biasag/n21001intelplatform00srvradm.htm">Object Spawner Messages</a> in "Appendix 1: Object Spawner and SAS OLAP Server Messages" in the <em>SAS<sup>®</sup> 9.4 Intelligence Platform: Application Server Administration Guid</em>e.</p>
<p>You can also enable more detailed logging within the object-spawner log by following the steps in <a href="https://go.documentation.sas.com/doc/en/bicdc/9.4/bisag/p1cu1oogaxct6jn1w9yv4wz03qwz.htm">Enable More Detailed Logging for SAS Object Spawner Troubleshooting</a> in "Chapter 10, Administering Logging for SAS Servers" of the <em>SAS<sup>®</sup> 9.4 Intelligence Platform: System Administration Guide, Fourth Edition</em>.</p>
<h3 style="color: dodgerblue;">Example and possible cause</h3>
<p>Let’s look at an example of how the object-spawner log can be helpful.</p>
<p>Suppose that the stored-process server fails to validate. Within the object-spawner log, you might see an error like the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #ff0000;">Error</span> authenticating user domain\sassrv <span style="color: #0000ff;">in</span> function LogonUser. <span style="color: #ff0000;">Error</span> <span style="color: #2e8b57; font-weight: bold;">1326</span> <span style="color: #66cc66;">&#40;</span>The user name <span style="color: #0000ff;">or</span> password is incorrect. <span style="color: #66cc66;">&#41;</span>.
&nbsp;
The credentials specified for the SASApp – Stored Process Server <span style="color: #66cc66;">&#40;</span>A5WN99NR.AZ000007<span style="color: #66cc66;">&#41;</span> server definition failed to authenticate. Therefore this server definition will <span style="color: #0000ff;">not</span> be included.</pre></td></tr></table></div>

<p>With this type of error, you might have an invalid <tt><strong>sassrv</strong></tt> password. You can check the password by trying to log on to the server directly with the <tt><strong>sassrv</strong></tt> user ID. If the logon is successful, open SAS<sup>®</sup> Management Console and verify that the password is correct in the metadata, as follows:</p>
<ol>
<li>In SAS<sup>®</sup> Management Console, select <strong>User Manager</strong>.</li>
<li>Locate the <strong>SAS General Servers</strong> group. Then, right-click and select <strong>Properties</strong>.</li>
<li>Click the <strong>Accounts</strong> tab.</li>
<li>Select the <strong><tt>sassrv</tt></strong> user ID. Then click <strong>Edit</strong>.</li>
<li>Update the password to what was successful on the operating system.</li>
<li>Restart the object spawner.</li>
<li>Check the logs again to verify that the error is resolved.</li>
</ol>
<h2 style="color: dodgerblue;">Object-spawner console log</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>The object-spawner console log, available only on UNIX platforms, does not actually contain information about the object spawner. Instead, this log contains STDERR and STDOUT messages about the applications that are launched by the object spawner. The syntax for this log's name ObjectSpawner_console_<em>machine-name</em>.log.</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>Under UNIX, the default location for the object-spawner console log is <tt><strong><em>SAS-configuration-directory</em>/Lev1/ObjectSpawner/Logs</strong></tt>.</p>
<h3 style="color: dodgerblue;">Why</h3>
<p>Here are some reasons why you should check this log:</p>
<ul>
<li>SAS modules are missing. The program tries to run SAS modules that are not present in your environment.</li>
<li>Possible memory issues occur.</li>
<li>Storage or space issues occur.</li>
<li>Possible encoding issues occur.</li>
<li>Library permission issues occur.</li>
</ul>
<p>The following error is an example of one that you might find in the object-spawner console log:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #ff0000;">ERROR</span>: Could <span style="color: #0000ff;">not</span> find extension: <span style="color: #66cc66;">&#40;</span>sasgis<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>This error can occur when someone or some component runs code that either checks for the existence of certain SAS modules or that contains references to certain SAS modules that are not present in your environment. Because these modules do not exist, errors are written to the log. This behavior is expected, and it is not indicative of any larger issue. So, you can ignore these messages.</p>
<h3 style="color: dodgerblue;">Example and possible cause</h3>
<p>Let’s look at an example of how the object-spawner console log can be helpful.</p>
<p>Suppose that your program generates a segmentation violation, but there is no indication as to why that happens. Within the object-spawner console log, you might see an error like the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #ff0000;">ERROR</span>: No space <span style="color: #0000ff;">left</span> <span style="color: #0000ff;">on</span> device</pre></td></tr></table></div>

<p>This type of error is an indication that you might be running out of disk space. Try adding more space, point to a network drive, or use smaller files.</p>
<h2 style="color: dodgerblue;">SAS<sup>®</sup> Stored Process Server log</h2>
<p>You need to enable verbose logging to see every stored process that runs through the server. For more details about verbose logging, see <a href="https://support.sas.com/kb/34/114.html">SAS Note 34114</a>, "Creating a detailed SAS<sup>®</sup> Stored Process Server log by default."</p>
<h3 style="color: dodgerblue;">What</h3>
<p>The syntax for the SAS Stored Process Server log name is SASApp_STPServer_<em>yyyy-mm-dd_machine-name_process-ID</em>.log.</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>The default locations for the stored-process server log are as follows:</p>
<ul>
<li><strong>Windows: <tt><em>SAS-configuration-directory</em>\Lev1\SASApp\StoredProcessServer\Logs</tt></strong></li>
<li><strong>UNIX: <tt><em>SAS-configuration-directory</em>/Lev1/SASApp/StoredProcessServer/Logs</tt></strong></li>
</ul>
<h3 style="color: dodgerblue;">Why</h3>
<p>Here are the reasons that you might need to check this log:</p>
<ul>
<li>Performance problems occur.</li>
<li>You do not receive any results. That is, the stored process runs, but it does not return an error, a warning, or the expected results.</li>
</ul>
<p>Here is an example of an error that you might see in the log:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #ff0000;">ERROR</span>: A lock is <span style="color: #0000ff;">not</span> available for library.dataset.<span style="color: #000080; font-weight: bold;">data</span>
<span style="color: #ff0000;">ERROR</span>: Lock held <span style="color: #0000ff;">by</span> process <span style="color: #2e8b57; font-weight: bold;">26834</span></pre></td></tr></table></div>

<p>This error indicates that the data set that is shown in the error cannot be locked for processing because the lock is held by another process. Further investigation of the stored-process server log that contains process ID 26834 shows the DATA step that is also reading from the same data set, which causes the lock.</p>
<p>Here is another error that you might see in this log:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #ff0000;">ERROR</span>: No logical assign for <span style="color: #0000ff;">filename</span> _WEBOUT.</pre></td></tr></table></div>

<h3 style="color: dodgerblue;">Possible causes</h3>
<p>The two main reasons for this error are as follows:</p>
<ul>
<li>The %STPBEGIN and %STPEND macros are enabled.</li>
<li>The item <tt><strong><em>Package</em></strong></tt> is selected under the <strong>Result capabilities</strong> section (via <strong>Execution Options ► Result capabilities</strong> in either SAS Management Console or SAS Enterprise Guide)</li>
</ul>
<p>The object-spawner console log is often needed in conjunction with the object-spawner log so that you can evaluate the communication between them.</p>
<h2 style="color: dodgerblue;">SAS<sup>®</sup> Stored Process web-application log</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>The SAS Stored Process web-application log resides on the middle-tier machine, and the syntax for the log's name is SASStoredProcess9.4.log. (<strong>Note:</strong> The 9.4 in SASStoredProcess9.4.log will change with new releases.)</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>The default locations for this log are as follows:</p>
<ul>
<li><strong>Windows: <tt><em>SAS-configuration-directory</em>\Lev1\Web\Logs\SASServer1_1</tt></strong></li>
<li><strong>UNIX: <tt><em>SAS-configuration-directory</em>/Lev1/Web/Logs/SASServer1_1</tt></strong></li>
</ul>
<h3 style="color: dodgerblue;">Why</h3>
<p>Here are some scenarios for which you might want to check this log:</p>
<ul>
<li>HTTP errors are displayed in the browser when you submit the stored process from the SAS Stored Process Web Application.</li>
<li>Pages in the stored-process web application (for example, the welcome page, index page, or custom input form) do not load or they take a long time to load.</li>
<li>A dynamic prompt cannot load.</li>
</ul>
<h3 style="color: dodgerblue;">Examples</h3>
<p>The following error occurs when dynamic prompts from a data set and the SAS General Servers user group are denied ReadMetadata permission in SAS Management Console for that specific stored process:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #2e8b57; font-weight: bold;">2021</span>-07-<span style="color: #2e8b57; font-weight: bold;">30</span> <span style="color: #2e8b57; font-weight: bold;">15</span>:01:<span style="color: #2e8b57; font-weight: bold;">43</span>,<span style="color: #2e8b57; font-weight: bold;">494</span> <span style="color: #66cc66;">&#91;</span>tomcat-http--<span style="color: #2e8b57; font-weight: bold;">10</span><span style="color: #66cc66;">&#93;</span> WARN <span style="color: #66cc66;">&#91;</span>sasdemo<span style="color: #66cc66;">&#93;</span> com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider - Cannot <span style="color: #0000ff;">resolve</span> <span style="color: #000080; font-weight: bold;">data</span> type
<span style="color: #2e8b57; font-weight: bold;">2021</span>-07-<span style="color: #2e8b57; font-weight: bold;">30</span> <span style="color: #2e8b57; font-weight: bold;">15</span>:01:<span style="color: #2e8b57; font-weight: bold;">43</span>,<span style="color: #2e8b57; font-weight: bold;">505</span> <span style="color: #66cc66;">&#91;</span>tomcat-http--<span style="color: #2e8b57; font-weight: bold;">10</span><span style="color: #66cc66;">&#93;</span> <span style="color: #ff0000;">ERROR</span> <span style="color: #66cc66;">&#91;</span>sasdemo<span style="color: #66cc66;">&#93;</span> com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider - Unable to find physical <span style="color: #0000ff;">table</span>
com.sas.storage.exception.ServerConnectionException: Unable to find physical <span style="color: #0000ff;">table</span>
	at com.sas.prompts.valueprovider.dynamic.DataProviderUtil.getLibrary<span style="color: #66cc66;">&#40;</span>DataProviderUtil.java:<span style="color: #2e8b57; font-weight: bold;">163</span><span style="color: #66cc66;">&#41;</span>
	at com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider.setConnection<span style="color: #66cc66;">&#40;</span>PromptColumnValueProvider.java:<span style="color: #2e8b57; font-weight: bold;">815</span><span style="color: #66cc66;">&#41;</span>
	at com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider.getValuesAsList<span style="color: #66cc66;">&#40;</span>PromptColumnValueProvider.java:<span style="color: #2e8b57; font-weight: bold;">647</span><span style="color: #66cc66;">&#41;</span>
	at com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider.getValues<span style="color: #66cc66;">&#40;</span>PromptColumnValueProvider.java:<span style="color: #2e8b57; font-weight: bold;">633</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>The following pop-up message occurs because the SAS General Servers user group or the <tt><strong><em>sasdemo</em></strong></tt> user ID are denied permission to the data set that is needed for the prompts for a stored process.</p>
<p><img loading="lazy" class="aligncenter size-full wp-image-36015" src="https://blogs.sas.com/content/sgf/files/2021/10/Error.png" alt="Unable to execute query: SQL passthru expression contained these errors: ERROR: File MYLIB.MYCLASS.DATA does not exist" width="848" height="151" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Error.png 1695w, https://blogs.sas.com/content/sgf/files/2021/10/Error-300x53.png 300w, https://blogs.sas.com/content/sgf/files/2021/10/Error-1024x182.png 1024w, https://blogs.sas.com/content/sgf/files/2021/10/Error-768x137.png 768w, https://blogs.sas.com/content/sgf/files/2021/10/Error-1536x274.png 1536w" sizes="(max-width: 848px) 100vw, 848px" /></p>
<p>When you run a stored process from the SAS Stored Process Web Application, it is often helpful to add debugging options to the end of the URL by using the reserved macro variable _DEBUG. The following example URL demonstrates how to use the TRACE and LOG options to obtain pertinent information in the log that is produced in the browser.</p>
<p style="padding-left: 120px;"><tt><strong>http://<em>your.web.server</em>:8080/SASStoredProcess/do?_program=/STP_Examples/test1&amp;_debug=trace,log</strong></tt></p>
<p>For a complete list of _DEBUG= values, see <a href="file:///C:/Users/saskcw/AppData/Local/Temp/SiriusV2/List of Valid Debugging Keywords">List of Valid Debugging Keywords</a> in "Chapter 7: Building a Web Application with SAS<sup>®</sup> Stored Processes" in the <em>SAS<sup>®</sup> 9.4 Stored Processes: Developer's Guide, Third Edition.</em></p>
<h2 style="color: dodgerblue;">Workspace-server log</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>You must request logging for the workspace-server log because it is not one that is enabled, by default. The syntax for the log's name is SASApp_WorkspaceServer_yyyy-mm-dd_machine-name_process-ID.log.</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>As mentioned earlier, you must request logging for this log, as follows:</p>
<ul>
<li><strong>Windows:</strong> In the sasv9_usermods.cfg file that resides in <tt><strong><em>SAS-configuration-directory</em>\Lev1\SASApp\WorkspaceServer\</strong></tt> directory, add the following command to turn on logging:

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">-logconfigloc SAS-configuration-directory\Lev1\SASApp\WorkspaceServer\logconfig.trace.xml<span style="color: #a020f0;">&quot;</span></pre></td></tr></table></div>

<p>This setting generates the log file in <tt><strong><em>SAS-configuration-directory</em>\Lev1\SASApp\WorkspaceServer\Logs</strong></tt>.</li>
<li><strong>UNIX:</strong> In the sasv9_usermods.cfg file that resides in <tt><strong><em>SAS-configuration-directory</em>/Lev1/SASApp/WorkspaceServer/logconfig.trace.xml"<br />
to /Lev1/SASApp/WorkspaceServer/</strong></tt> directory, add the following command to turn on logging:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">-LOGCONFIGLOC SAS-configuration-directory/Lev1/SASApp/WorkspaceServer/logconfig.trace.xml<span style="color: #a020f0;">&quot;</span></pre></td></tr></table></div>

<p>This setting generates the log file that resides in <tt><strong><em>SAS-configuration-directory</em>/Lev1/SASApp/WorkspaceServer/Logs</strong></tt>.</li>
</ul>
<h3 style="color: dodgerblue;">Why</h3>
<p>If you run the stored process from the SAS Stored Process Web Application with the server set to the workspace server, you need to consult this log for any errors or warnings. Running the stored process from SAS Enterprise Guide produces a log directly in the application. You need to consult the workspace server log in either of these circumstances:</p>
<ul>
<li>when <tt><strong><em>Default server</em></strong></tt> is selected as the server type in the stored-process properties</li>
<li>when you submit the stored process from SAS Enterprise Guide</li>
</ul>
<h2 style="color: dodgerblue;">Pooled workspace-server Log</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>The syntax for the pooled workspace-server log's name is SASApp_PooledWSServer_<em>yyyy-mm-dd_machine-name_process-ID</em>.log.</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>The default locations for this log are as follows:</p>
<ul>
<li><strong>Windows: <tt><em>SAS-configuration-directory</em>\ Lev1\SASApp\PooledWorkspaceServer\Logs</tt></strong></li>
<li><strong>UNIX: <tt><em>SAS-configuration-directory</em>/Lev1/SASApp/PooledWorkspaceServer/Logs</tt></strong></li>
</ul>
<h3 style="color: dodgerblue;">Why</h3>
<p>The pooled workspace server loads dynamic prompt values in the SAS Stored Process web application. So, you need this log if a dynamic prompt does not load.</p>
<h2 style="color: dodgerblue;">SAS<sup>®</sup> Metadata Server Log</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>The syntax for the SAS Metadata Server log' name is SASMeta_MetadataServer_<em>yyyy-mm-dd_machine-name_process-ID</em>.log</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>The default locations for the metadata-server log are as follows:</p>
<ul>
<li><strong>Windows: <tt><em>SAS-configuration-directory</em>\Lev1\SASMeta\MetadataServer\Logs</tt></strong></li>
<li><strong>UNIX: <tt><em>SAS-configuration-directory</em>/Lev1/SASMeta/MetadataServer/Logs</tt></strong></li>
</ul>
<h3 style="color: dodgerblue;">Why</h3>
<p>This log is helpful for issues with the LIBNAME META engine and metadata permissions.</p>
<p>The following error is written to the metadata-server log when no metadata identity is associated with the user name and password.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #ff0000;">ERROR</span> <span style="color: #66cc66;">&#91;</span>00000779<span style="color: #66cc66;">&#93;</span> <span style="color: #2e8b57; font-weight: bold;">28</span>:billyw - User Folders cannot be created <span style="color: #0000ff;">or</span> retrieved <span style="color: #0000ff;">if</span> connected user ID is <span style="color: #0000ff;">not</span> a person identity. Must be connected <span style="color: #0000ff;">as</span> a person identity <span style="color: #0000ff;">or</span> valid person name must be passed <span style="color: #0000ff;">in</span> request.</pre></td></tr></table></div>

<p>The following messages might also be written to this log when you try to open SAS Management Console and when the user <tt><strong><em>billyw</em></strong></tt> requires <strong>log on as a batch job</strong> user rights at the operating system level.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #2e8b57; font-weight: bold;">20100122</span>:13.00.36.82: 00002410:<span style="color: #0000ff;">NOTE</span>:    User tbanks probably does <span style="color: #0000ff;">not</span> have the <span style="color: #0000ff;">right</span> to <span style="color: #0000ff;">log</span> <span style="color: #0000ff;">on</span> <span style="color: #0000ff;">as</span> a batch job.
<span style="color: #2e8b57; font-weight: bold;">20100122</span>:13.00.36.82: 00002410:<span style="color: #ff0000;">ERROR</span>:   <span style="color: #ff0000;">Error</span> authenticating user tbanks <span style="color: #0000ff;">in</span> function LogonUser.  <span style="color: #ff0000;">Error</span> <span style="color: #2e8b57; font-weight: bold;">1385</span> <span style="color: #66cc66;">&#40;</span>Logon failure: the user has <span style="color: #0000ff;">not</span> been granted the requested logon type at this computer. <span style="color: #66cc66;">&#41;</span>.
<span style="color: #2e8b57; font-weight: bold;">20100122</span>:13.00.36.82: 00002410:<span style="color: #ff0000;">ERROR</span>:   Access denied.</pre></td></tr></table></div>

<h2 style="color: dodgerblue;">Infrequently Used Logs</h2>
<h3 style="color: dodgerblue;">Windows Event Viewer log</h3>
<p>The Windows Event Viewer contains several logs that are used less frequently than the aforementioned logs. This fact in no way diminishes their effectiveness when you are troubleshooting stored-process issues. SAS Technical Support will request these logs from you for an issue if it is necessary.</p>
<p>Although the event viewer contains several logs, SAS Technical Support reviews only the application log, the system log, and the security log for errors that are related to start-up and other failures in the SAS Stored Process Server (or any SAS server).</p>
<p>If the <tt><strong>sassrv</strong></tt> user ID cannot write to the Logs directory, you receive a message in this log.</p>
<p>If a server is stopped or started, those behaviors register in these logs. Hopefully, this review of the various logs that are related to debugging stored-process issues will assist your troubleshooting efforts.</p>
<h2 style="color: dodgerblue;">ERROR_<em>yyyy-mm-dd</em>-time.log</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>This web-server log is useful when you have catastrophic failures in loading or running a stored process in a SAS web application. The syntax for this log's name is ERROR_<em>yyyy-mm-dd</em>-time.log.</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>The default locations for this log are as follows:</p>
<ul>
<li><strong>Windows: <tt><em>SAS-configuration-directory</em>\Lev1\Web\WebServer\logs</tt></strong></li>
<li><strong>UNIX: <tt><em>SAS-configuration-directory</em>/Lev1/Web/WebServer/logs</tt></strong></li>
</ul>
<h3 style="color: dodgerblue;">Why</h3>
<p>Here are some reasons why you should check this log:</p>
<ul>
<li>Java errors are returned in the browser when you try to load or run a stored process using the SAS Stored Process Web Application.</li>
<li>Connection errors occur between the web server and the tc Server.</li>
</ul>
<p>Here is an example of an error that you might find in this log:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">error</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>OS <span style="color: #2e8b57; font-weight: bold;">10061</span><span style="color: #66cc66;">&#41;</span>No connection could be made because the target machine actively refused it.  : proxy: HTTP: attempt to connect to <span style="color: #2e8b57; font-weight: bold;">192.168</span>.<span style="color: #0000ff;">x</span>.xxx:<span style="color: #2e8b57; font-weight: bold;">8080</span> <span style="color: #66cc66;">&#40;</span>machine-name<span style="color: #66cc66;">&#41;</span> failed</pre></td></tr></table></div>

<p>This error might occur when your servers are down or when they are restarting and are not active yet.</p>
<h3 style="color: dodgerblue;">Example and possible cause</h3>
<p>Let’s look at an example of how the ERROR_<em>yyyy-mm-dd</em>-time log can be helpful.</p>
<p>Suppose that you try to run a stored process through the SAS Stored Process Web Application and you cannot load any SAS 9.4 web applications after you enter your user ID and password. If you check this log, you might see errors like the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">No connection could be made because the target machine actively refused it. : proxy: HTTP: attempt to connect to <span style="color: #2e8b57; font-weight: bold;">192.168</span>.<span style="color: #0000ff;">x</span>.xxx:<span style="color: #2e8b57; font-weight: bold;">8080</span> <span style="color: #66cc66;">&#40;</span>machine-name<span style="color: #66cc66;">&#41;</span> failed
&nbsp;
ap_proxy_connect_backend disabling worker for <span style="color: #66cc66;">&#40;</span>machine-name<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>The secondary middle-tier node is in a clustered environment, but it configured incorrectly. For a circumvention, see <a href="https://support.sas.com/kb/55/904.html">SAS Note 55904</a>, "You cannot access any SAS® 9.4 web applications when the secondary middle-tier node is in a clustered environment."</p>
<h2 style="color: dodgerblue;">Localhost_access_log..<em>yyyy-mm-dd</em>.txt</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>This log shows the sequence and query strings of URLs that are submitted through the SAS Web Application Server (for all web applications that use this application server). This log lists activity sequentially and includes HTTP status codes for each URL. The syntax for this log's name is Localhost_access_log..<em>yyyy-mm-dd</em>.txt.</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>The default locations for this log are as follows:</p>
<ul>
<li><strong>Windows: <tt><em>SAS-configuration-directory</em>\Lev1\Web\WebAppServer\SASServer1_1\logs</tt></strong></li>
<li><strong>UNIX: <tt><em>SAS-configuration-directory</em>/Lev1/Web/WebAppServer/SASServer1_1/logs</tt></strong></li>
</ul>
<h3 style="color: dodgerblue;">Why</h3>
<p>Here are some reasons why you should check this log:</p>
<ul>
<li>A page cannot load or the URL is invalid.</li>
<li>Performance problems occur.</li>
<li>You need a good way to trace the stored-process activity after you click the <strong>Run</strong> button in web applications only.</li>
</ul>
<p>Here is an example of a message that you might see in this log:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #a020f0;">&quot;POST /SASLogon/v1/tickets HTTP/1.1&quot;</span> <span style="color: #2e8b57; font-weight: bold;">404</span> <span style="color: #2e8b57; font-weight: bold;">796</span></pre></td></tr></table></div>

<h3 style="color: dodgerblue;">Example and possible cause</h3>
<p>Let’s look at an example of how this log can be helpful. Suppose that you cannot log on to the SAS Stored Process Web Application. If you check this log, you might see a message like the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">GET /SASStoredProcess/j_spring_cas_security_check?ticket=ST-<span style="color: #2e8b57; font-weight: bold;">9994</span>-zpD2sFdBmayXEuoj4cya-cas HTTP/<span style="color: #2e8b57; font-weight: bold;">1.1</span><span style="color: #a020f0;">&quot; 401 802</span></pre></td></tr></table></div>

<p>In this example, you can see that the issue is a 401 HTTP return code.</p>
<p>If the servers have just been restarted, try waiting a little longer for them to start up. If that is not the issue, the server might be down. The best approach is to stop and then restart the servers. Because of dependencies, it is important to start the servers in the correct order. You can find the correct order in <a href="https://go.documentation.sas.com/doc/en/bicdc/9.4/bisag/p0d9d5nzmd8i4yn1usv2l22vpa7t.htm">Overview of Server Operation</a>, in "Chapter 6: Operating Your Servers" of the <em>SAS<sup>®</sup> Intelligence Platform: System Administration Guide, Fourth Edition</em>.</p>
<h2 style="color: dodgerblue;">Access_<em>yyyy-mm-dd-time</em>.log</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>This log shows the sequence and query strings of URLs that are submitted through the SAS Web Server. The syntax for the name of this log is access_<em>yyyy-mm-dd-time</em>.log.</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>The default locations for this log are as follows:</p>
<ul>
<li><strong>Windows: <tt><em>SAS-configuration-directory</em>\Lev1\Web\WebServer\logs</tt></strong></li>
<li><strong>UNIX: <tt><em>SAS-configuration-directory</em>/Lev1/Web/WebServer/logs</tt></strong></li>
</ul>
<h3 style="color: dodgerblue;">Why</h3>
<p>Here are some reasons why you would check this log:</p>
<ul>
<li>A connection error occurs when you submit a stored process.</li>
<li>Java errors occur in the browser.</li>
<li>When you evaluate a performance problem, timestamps in the log confirm when the web server received the request and what was in the request.</li>
<li>The output that is produced by the stored process does not match the expected output based on the prompt selections that are available when you submit the stored process.</li>
</ul>
<p>Here is an example of a message that you might see in this log:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #a020f0;">&quot;GET /SASTheme_default/themes/ThemeXMLFiles.config HTTP/1.1&quot;</span> <span style="color: #2e8b57; font-weight: bold;">503</span> <span style="color: #2e8b57; font-weight: bold;">299</span></pre></td></tr></table></div>

<p>This error might occur because the servers are down or are in the process of restarting and are not active yet.</p>
<h3 style="color: dodgerblue;">Example and possible cause</h3>
<p>Let’s look at an example of how the access_<em>yyyy-mm-dd</em>-time log can be helpful.</p>
<p>Suppose that you are trying to run a stored process through the SAS web application and you receive a connection error. If you check this log, you might see a message like the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #a020f0;">&quot;GET /SASLogon/proxy?pgt=TGT-6-aGakal9b2VGBg3dnNTbbwiVALOWqBSem9E3cVWehDD35vegmxI-cas&amp;amp;targetService=http%3A%2F%2FLazySecurityContext HTTP/1.1&quot;</span> <span style="color: #2e8b57; font-weight: bold;">502</span> <span style="color: #2e8b57; font-weight: bold;">407</span></pre></td></tr></table></div>

<p>The message above shows a 502 HTTP return code. This error indicates that the server, while acting as a gateway or proxy, received an invalid response from the upstream server. If the servers were just restarted, try waiting a little longer for them to start back up. If that is not the issue, then a server might be down. The best approach is to stop and restart the servers. Because of dependencies, it is important to start the servers in the correct order. You can find the correct order in <a href="https://go.documentation.sas.com/doc/en/bicdc/9.4/bisag/p0d9d5nzmd8i4yn1usv2l22vpa7t.htm">Overview of Server Operation</a>, in "Chapter 6: Operating Your Servers" of the <em>SAS<sup>®</sup> Intelligence Platform: System Administration Guide, Fourth Edition</em>.</p>
<h2 style="color: dodgerblue;">Server.log</h2>
<h3 style="color: dodgerblue;">What</h3>
<p>This log is helpful if a stored-process web application generates an HTPP, browser, or generic error in the browser when it loads a page or results that are returned from a stored process.</p>
<h3 style="color: dodgerblue;">Where</h3>
<p>The default locations for this log are as follows:</p>
<ul>
<li><strong>Windows: <tt><em>SAS-configuration-directory</em>\Lev1\Web\WebAppServer\SASServer1_1\logs</tt></strong></li>
<li><strong>UNIX: <tt><em>SAS-configuration-directory</em>/Lev1/Web/WebAppServer/SASServer1_1/logs</tt></strong></li>
</ul>
<h3 style="color: dodgerblue;">Why</h3>
<p>Here are some reasons why you would check this log:</p>
<ul>
<li>The SAS Stored Processes web application is not working.</li>
<li>Requests time out.</li>
<li>A configuration change is made to one of the web applications (for example, an increase to the time-out for the stored-process web application).</li>
<li>A generic error is displayed in the SAS Stored Processes web application when you run a stored process.</li>
</ul>
<p>Here is an example of a message that you might find in this log:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">java.io.IOException: Cannot bind to URL</pre></td></tr></table></div>

<p>One possible reason for this type of error is network issues at the site where the stored process is run.</p>
<h3 style="color: dodgerblue;">Example and possible cause</h3>
<p>Let’s look at an example of how the server.log file can be helpful.</p>
<p>Suppose that you want to run a stored process through the SAS Web Application and you receive a generic error that says <tt>The system is experiencing problems. Please contact your system administrator.</tt> If you check this log, you might see a message like the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #ff0000;">ERROR</span> <span style="color: #66cc66;">&#40;</span>ContainerBackgroundProcessor<span style="color: #66cc66;">&#91;</span>StandardEngine<span style="color: #66cc66;">&#91;</span>Catalina<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#91;</span>org.apache.catalina.core.ContainerBase<span style="color: #66cc66;">&#93;</span> Unexpected death of background thread ContainerBackgroundProcessor<span style="color: #66cc66;">&#91;</span>StandardEngine<span style="color: #66cc66;">&#91;</span>Catalina<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span>
java.lang.OutOfMemoryError: Java heap space</pre></td></tr></table></div>

<p>There is insufficient memory available to process the request. As a possible workaround, you need to modify the setenv.bat file that resides on Windows in <tt><strong><em>SAS-configuration-directory</em>\Lev1\Web\Webappserver\Sasserver1_1\bin\</strong></tt> or the setenv.sh in <tt><strong><em>SAS-configuration-directory</em>/Lev1/Web/WebAppServer/Sasserver1_1/bin/</strong></tt> on UNIX. You need to edit the JVM_OPTS value by changing the <tt><strong><em>-Xmx4096m -Xms1024m</em></strong></tt> parameter to the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">-Xmx8092m -Xms8092m</pre></td></tr></table></div>

<p>Making this change requires the restart of the SAS Web Application Server if only the webappserver script is updated.</p>
<h1 style="color: dodgerblue;">Conclusion</h1>
<p>Hopefully, this review of logs that are related to debugging stored-process issues will assist your troubleshooting efforts. When you request help from SAS Technical Support, these are some of the logs that you will be asked to send so that Technical Support can better determine the cause of your problem.</p>
<h2 style="color: dodgerblue;">Learn more</h2>
<ul>
<li><a href="https://blogs.sas.com/content/sgf/2020/02/28/jobs-stored-processes-in-viya/">Jobs: Stored processes in Viya</a></li>
<li><a href="https://support.sas.com/rnd/itech/doc9/dev_guide/stprocess/program.html">Creating Stored Processes - SAS Support</a></li>
<li><a href="https://support.sas.com/rnd/itech/doc9/dev_guide/stprocess/index.html">Developer's Guide: SAS Stored Processes</a></li>
</ul>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/20/debugging-a-stored-process-problem/">Debugging a stored-process problem</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=3GyJTpaHQ3s:Jd8cpg-rkdA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=3GyJTpaHQ3s:Jd8cpg-rkdA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=3GyJTpaHQ3s:Jd8cpg-rkdA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=3GyJTpaHQ3s:Jd8cpg-rkdA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=3GyJTpaHQ3s:Jd8cpg-rkdA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=3GyJTpaHQ3s:Jd8cpg-rkdA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=3GyJTpaHQ3s:Jd8cpg-rkdA:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=3GyJTpaHQ3s:Jd8cpg-rkdA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=3GyJTpaHQ3s:Jd8cpg-rkdA:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/10/20/debugging-a-stored-process-problem/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2020/02/ProblemSolvers-150x150.jpg" />
	</item>
		<item>
		<title>Introducing TRIMS function to remove any leading and/or trailing characters from SAS strings</title>
		<link>https://blogs.sas.com/content/sgf/2021/10/14/introducing-trims-function-to-remove-any-leading-and-or-trailing-characters-from-sas-strings/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/10/14/introducing-trims-function-to-remove-any-leading-and-or-trailing-characters-from-sas-strings/#comments</comments>
		
		<dc:creator><![CDATA[Leonid Batkhan]]></dc:creator>
		<pubDate>Thu, 14 Oct 2021 12:00:33 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[character data]]></category>
		<category><![CDATA[data step]]></category>
		<category><![CDATA[proc FCMP]]></category>
		<category><![CDATA[SAS Programmers]]></category>
		<category><![CDATA[tips & techniques]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=35709</guid>

					<description><![CDATA[<p>Leonid Batkhan introduces multipurpose TRIMS function that removes any leading, trailing or both leading and trailing characters from SAS strings.</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/14/introducing-trims-function-to-remove-any-leading-and-or-trailing-characters-from-sas-strings/">Introducing TRIMS function to remove any leading and/or trailing characters from SAS strings</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><img loading="lazy" width="800" height="600" class="alignright size-full wp-image-35712" src="https://blogs.sas.com/content/sgf/files/2021/10/trimming-left-and-right.jpg" alt="Trimming strings left and right" style="width: 50%" srcset="https://blogs.sas.com/content/sgf/files/2021/10/trimming-left-and-right.jpg 800w, https://blogs.sas.com/content/sgf/files/2021/10/trimming-left-and-right-300x225.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/10/trimming-left-and-right-768x576.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></p>
<p>I am pretty sure you have never heard of the TRIMS function, and I would be genuinely surprised if you told me otherwise. This is because this function does not exist (at least at the time of this writing).</p>
<p>But don’t worry, the difference between "nonexistence" and "existence" is only a matter of time, and from now it is less than a blog away. Let me explain. Recently, I published two complementary blog posts:</p>
<p>[1] <a href="https://blogs.sas.com/content/sgf/2021/08/23/removing-leading-characters-from-sas-strings/">Removing leading characters from SAS strings</a></p>
<p>[2] <a href="https://blogs.sas.com/content/sgf/2021/09/02/removing-trailing-characters-from-sas-strings/">Removing trailing characters from SAS strings</a></p>
<p>While working on these pieces and researching “prior art” I stumbled upon a multipurpose function in the <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/fedsqlref/titlepage.htm">SAS FedSQL Language</a> that alone does either one or both of these things – remove leading or/and trailing characters from SAS strings.</p>
<h2><strong>FedSQL Language and Proc FedSQL</strong></h2>
<p>The FedSQL language is the SAS proprietary implementation of the <a href="https://en.wikipedia.org/wiki/SQL:1999">ANSI SQL:1999 core standard</a>. Expectedly, the FedSQL language is implemented in SAS by means of the <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/proc/n18135hihi4fi0n1ra7ge29nh3hw.htm">FedSQL procedure</a> (PROC FEDSQL). This procedure enables you to submit FedSQL language statements from a Base SAS session, and it is supported in both SAS 9.4 and SAS Viya.</p>
<p>Using the FEDSQL procedure, you can submit FedSQL language statements to SAS and third-party data sources that are accessed with SAS and SAS/ACCESS library engines. Or, if you have SAS Cloud Analytic Services (CAS) configured, you can submit FedSQL language statements to the CAS server.</p>
<h2><strong>FedSQL TRIM function</strong></h2>
<p>FedSQL language has its own vast <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/fedsqlref/p0cqwwomu4bgebn1e0sjztf3ul9o.htm">FedSQL Functions</a> library with hundreds of functions many of which replicate <a href="https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/p1q8bq2v0o11n6n1gpij335fqpph.htm">SAS 9.4 Functions</a>. Many, but not all. Deep inside this FedSQL functions library, there is a unique treasure modestly called <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/fedsqlref/n1x15ai82patq8n1v4xryc1phpdr.htm">TRIM Function</a> which is quite different from the <a href="https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/n1io938ofitwnzn18e1hzel3u9ut.htm">BASE SAS Language TRIM() function</a>.</p>
<p>While SAS 9.4 BASE TRIM() function capabilities are quite limited - it removes just trailing blanks from a character string, the FedSQL TRIM() function is way much more powerful. This triple-action function can remove not just trailing blanks, but also leading blanks, as well as both, leading and trailing blanks. On top of it, it can remove not just blanks, but any characters (although one character at a time). See for yourself, this function has the following pretty self-explanatory syntax:</p>
<div style="width:max-content;width:fit-content;background-color:#eef5f9;border: 3px solid #007dc3;border-radius:9px;padding:7px">
<strong>TRIM</strong>( [BOTH | LEADING | TRAILING] [trim-character] FROM column)
</div>
<p>Here trim-character specifies one character (in single quotations marks) to remove from column. If trim-character is not specified, the function removes blanks.</p>
<p>While being called a function, it does not look like a regular SAS function where arguments are separated by commas.  It looks more like an SQL statement (which it understandably is – it is part of the FedSQL language). However, this function is available only in PROC FEDSQL; it’s not available in SAS DATA steps or other PROC steps. Still, it gives us pretty good idea of what such a universal function may look like.</p>
<h2><strong>User-defined function TRIMS to remove leading or/and trailing characters in SAS strings</strong></h2>
<p>Let’s build such a function by means of the <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/proc/n0pio2crltpr35n1ny010zrfbvc9.htm">PROC FCMP</a> for the outside the FedSQL usage (it is worth noticing that the <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/fedsqlref/fedsqlrefwhatsnew94.htm#p0bfs8bpl8yes1n1eu4uoa7vhefk">FCMP procedure is not supported for FedSQL</a>). To avoid confusion with the existing TRIM function we will call our new function <strong>TRIMS</strong> (with an ‘S’ at the end) which suits our purpose quite well denoting its plural purpose. First, we define what we are going to create.</p>
<div style="background-color:#f3ffeb;border: 3px solid #67912e;border-radius:9px;padding:7px">
<h4 style="background-color:#67912e;border-radius:5px;color:white;font-weight:bold;padding:3px 3px 3px 11px;margin-bottom:9px">User-defined TRIMS function</h4>
<p></p>
<div style="padding-left:20px">
<h3><strong>TRIMS Function</strong></h3>
<p>Removes leading characters, trailing characters, or both from a character string. </p>
<h3><strong>Syntax</strong></h3>
<div style="width:max-content;width:fit-content;background-color:#ffffff;border: 3px solid #67912e;border-radius:9px;padding:7px">
<strong>TRIMS(<em>function-modifier, string, trim-list, trim-list-modifier</em>)</strong>
</div>
<p></p>
<h3><strong>Required Arguments</strong></h3>
<ul>
<li><strong><em>function-modifier</em></strong> is a case-insensitive character constant, variable, or expression that specifies one of three possible operations:<br />
'L' or 'l' – removes leading characters.<br />
'T' or 't' – removes trailing characters.<br />
'B' or 'b' – removes both, leading and trailing characters.</li>
<li><strong><em>string</em></strong> is a case-sensitive character constant, variable, or expression that specifies the character string to be trimmed.</li>
<li><strong><em>trim-list</em></strong> is a case-sensitive character constant, variable, or expression that specifies character(s) to remove from the <strong>string</strong>.</li>
<li><strong><em>trim-list-modifier </em></strong>is a case-insensitive character constant variable, or expression that supplements the trim-list.<br />
The valid values are those <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/n1mdh2gvd5potjn14jipysvzn4o7.htm">modifiers of the FINDC function</a> that “<strong><em>add</em></strong>” groups of characters (e.g. 'a' or 'A', 'c' or 'C', 'd' or 'D', etc.) to the <strong><em>trim-list.</em></strong></li>
</ul>
</div>
</div>
<p>The following user-defined function implementation is based on the coding techniques described in the two previous posts, <a href="https://blogs.sas.com/content/sgf/2021/08/23/removing-leading-characters-from-sas-strings/">[1]</a> and <a href="https://blogs.sas.com/content/sgf/2021/09/02/removing-trailing-characters-from-sas-strings/">[2]</a> that I mentioned above. Here goes.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;">&nbsp;
<span style="color: #0000ff;">libname</span> funclib <span style="color: #a020f0;">'c:<span style="color: #000099; font-weight: bold;">\p</span>rojects<span style="color: #000099; font-weight: bold;">\f</span>unctions'</span>;
&nbsp;
<span style="color: #006400; font-style: italic;">/* delete previous function definition during debugging */</span>
<span style="color: #0000ff;">options</span> cmplib=funclib.userfuncs;
<span style="color: #000080; font-weight: bold;">proc fcmp</span> outlib=funclib.userfuncs.package1;
   deletefunc trims;
<span style="color: #000080; font-weight: bold;">run</span>;
&nbsp;
<span style="color: #006400; font-style: italic;">/* new function defintion */</span>
<span style="color: #000080; font-weight: bold;">proc fcmp</span> outlib=funclib.userfuncs.package1;
   function trims<span style="color: #66cc66;">&#40;</span>f $, str $, clist $, <span style="color: #0000ff;">mod</span> $<span style="color: #66cc66;">&#41;</span> $32767;
      <span style="color: #0000ff;">from</span> = <span style="color: #2e8b57; font-weight: bold;">1</span>;
      last = <span style="color: #0000ff;">length</span><span style="color: #66cc66;">&#40;</span>str<span style="color: #66cc66;">&#41;</span>;
      <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">upcase</span><span style="color: #66cc66;">&#40;</span>f<span style="color: #66cc66;">&#41;</span> <span style="color: #0000ff;">in</span> <span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'L'</span>, <span style="color: #a020f0;">'B'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #0000ff;">then</span> <span style="color: #0000ff;">from</span> = findc<span style="color: #66cc66;">&#40;</span>str, clist, <span style="color: #a020f0;">'K'</span>||<span style="color: #0000ff;">mod</span><span style="color: #66cc66;">&#41;</span>;
      <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">from</span>=<span style="color: #2e8b57; font-weight: bold;">0</span> <span style="color: #0000ff;">then</span> <span style="color: #0000ff;">return</span><span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">''</span><span style="color: #66cc66;">&#41;</span>;
      <span style="color: #0000ff;">if</span> <span style="color: #0000ff;">upcase</span><span style="color: #66cc66;">&#40;</span>f<span style="color: #66cc66;">&#41;</span> <span style="color: #0000ff;">in</span> <span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'T'</span>, <span style="color: #a020f0;">'B'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #0000ff;">then</span> last = findc<span style="color: #66cc66;">&#40;</span>str, clist, <span style="color: #a020f0;">'K'</span>||<span style="color: #0000ff;">mod</span>, -last<span style="color: #66cc66;">&#41;</span>; 
      <span style="color: #0000ff;">if</span> last=<span style="color: #2e8b57; font-weight: bold;">0</span> <span style="color: #0000ff;">then</span> <span style="color: #0000ff;">return</span><span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">''</span><span style="color: #66cc66;">&#41;</span>;
      <span style="color: #0000ff;">return</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">substr</span><span style="color: #66cc66;">&#40;</span>str, <span style="color: #0000ff;">from</span>, last-<span style="color: #0000ff;">from</span>+<span style="color: #2e8b57; font-weight: bold;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;      
   endfunc; 
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<h3><strong>Code highlights</strong></h3>
<ul>
<li>In the FUNCTION statement we assign the length of the returned value as $32767 to accommodate the longest possible character string.</li>
<li>In the function definition, we first assign initial values of the target substring positions as <tt>from=1</tt> and <tt>last=length(str)</tt>.</li>
<li>Then for <em>Leading</em> or <em>Both</em> character removal, we calculate an adjusted value of <tt>from</tt> as a position of the first character in <tt>str</tt> that is not listed in <tt>clist</tt> and not defined by the mod</li>
<li>If <tt>from=0</tt> then we return blank and stop further calculations as this means that ALL characters are to be removed.</li>
<li>Then for <em>Trailing</em> or <em>Both</em> character removal, we calculate an adjusted value of <tt>last</tt> as a position of the last character in <tt>str</tt> that is not listed in clist and not defined by the mod</li>
<li>If <tt>last=0</tt> then we return blank and stop further calculations as this means that ALL characters are to be removed.</li>
<li>And finally, we return a substring of <tt>str</tt> starting at the <tt>from</tt> position and ending at the <tt>last</tt> position, that is with the length of <tt>last-from+1</tt>.</li>
</ul>
<h2><strong>TRIMS function usage</strong></h2>
<p>Let’s define SAS data set SOURCE as follows:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="" style="font-family:monospace;">data SOURCE;
   input X $ <span style="">1</span>-<span style="">30</span>;
   datalines;
*00It's done*<span style="">2</span>*<span style="">1</span>**-
*--*<span style="">1</span>****<span style="">9</span>*<span style="">55</span>
<span style="">94</span>*Clean record-*00
;</pre></td></tr></table></div>

<p>In the following DATA step, we will create three new variables with removed leading (variable XL), trailing (variable XT) and both - leading and trailing (variable XB) characters <tt>'*'</tt> and <tt>'-'</tt> as well as any digits:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #0000ff;">options</span> cmplib=funclib.userfuncs;
<span style="color: #000080; font-weight: bold;">data</span> TARGET;
   <span style="color: #0000ff;">set</span> SOURCE;
   <span style="color: #0000ff;">length</span> XB XL XT $30;
   XB = trims<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'b'</span>, <span style="color: #0000ff;">X</span>, <span style="color: #a020f0;">'*-'</span>, <span style="color: #a020f0;">'d'</span><span style="color: #66cc66;">&#41;</span>;
   XL = trims<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'L'</span>, <span style="color: #0000ff;">X</span>, <span style="color: #a020f0;">'*-'</span>, <span style="color: #a020f0;">'d'</span><span style="color: #66cc66;">&#41;</span>;
   XT = trims<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">'t'</span>, <span style="color: #0000ff;">X</span>, <span style="color: #a020f0;">'*-'</span>, <span style="color: #a020f0;">'d'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>In this code we use the TRIMS function three times, each time with a different first argument to illustrate how this affects the outcome.</p>
<h3><strong>Usage highlights</strong></h3>
<ul>
<li>The first argument of the TRIMS function specifies whether we remove characters from both leading and trailing positions (<tt>'b'</tt>), from leading positions only (<tt>'L'</tt>), or from trailing positions only (<tt>'t'</tt>). This argument is case-insensitive. (I prefer using capital <tt>'L'</tt> for clarity since lowercase <tt>'l'</tt> looks like digit <tt>'1'</tt>).</li>
<li>The second argument specifies the name of the variable (X) that we are going to remove characters from (variable X is coming from the dataset SOURCE).</li>
<li>The third argument <tt>'*-'</tt> specifies which character (or characters) to remove. In our example we are removing <tt>'*'</tt> and <tt>'-'</tt>. If you do not need to explicitly specify any character here, you still must supply a null value (<tt>''</tt>) since it is a required argument. In this case, the fourth argument (trim-list-modifier) will determine the set of characters to be removed.</li>
<li>The fourth argument (case-insensitive) of the TRIMS function specifies the FINDC function modifier(s) to remove certain characters in bulk (in our example <tt>'d'</tt> will remove all digits). If such modifier is not needed, you still must supply a null value (<tt>''</tt>) since all four arguments of the TRIMS function are positional and required.</li>
<li>Please note that before calling the TRIMS function we assign the lengths for the variables XB, XL, and XT. Had we not done that, these variables would be assigned the maximum length of 32,767 bytes as specified in the TRIMS function definition.</li>
</ul>
<p>Here is the output data table TARGET showing the original string X and the resulting strings XB (Both leading and trailing characters removed), XL (Leading characters removed) and XT (Trailing characters removed) side by side:</p>
<p><img class="alignnone size-full wp-image-35715" src="https://blogs.sas.com/content/sgf/files/2021/10/leading-and-trailing-characters-removed.jpg" alt="Result of leading and trailing characters trimming" width="800" srcset="https://blogs.sas.com/content/sgf/files/2021/10/leading-and-trailing-characters-removed.jpg 1014w, https://blogs.sas.com/content/sgf/files/2021/10/leading-and-trailing-characters-removed-300x59.jpg 300w, https://blogs.sas.com/content/sgf/files/2021/10/leading-and-trailing-characters-removed-768x152.jpg 768w" sizes="(max-width: 1014px) 100vw, 1014px" /></p>
<h2><strong>Conclusion</strong></h2>
<p>The new TRIMS function presented in this blog post goes ways further the ubiquitous LEFT, TRIM, and STRIP functions that remove the leading (LEFT), trailing (TRIM), or both - leading and trailing (STRIP) blanks. The TRIMS function handles ANY characters, not just blanks. It also expands the character deletion functionality of the powerful  <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/fedsqlref/n1x15ai82patq8n1v4xryc1phpdr.htm">FedSQL TRIM function</a> beyond just removing any single leading and/or trailing character. The TRIMS function single-handedly removes any number of explicitly specified characters from either leading, trailing or both (leading and trailing) positions. Plus, it removes in bulk many implicitly specified characters. For example <tt>'d'</tt> modifier removes all digits, <tt>'du'</tt> modifier removes all digits (<tt>'d'</tt>) and all uppercase letters (<tt>'u'</tt>), <tt>'dup'</tt> modifier removes all digits (<tt>'d'</tt>), all uppercase letters (<tt>'u'</tt>) and all punctuation marks (<tt>'p'</tt>); and so on as described by the <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/n1mdh2gvd5potjn14jipysvzn4o7.htm">FINDC function modifiers</a>. The order in which modifier characters are listed does not matter.</p>
<h2><strong>Additional resources</strong></h2>
<ul>
<li><a href="https://blogs.sas.com/content/sgf/2021/08/23/removing-leading-characters-from-sas-strings/">Removing leading characters from SAS strings</a></li>
<li><a href="https://blogs.sas.com/content/sgf/2021/09/02/removing-trailing-characters-from-sas-strings/">Removing trailing characters from SAS strings</a></li>
<li><a href="https://blogs.sas.com/content/sgf/2021/02/22/deleting-a-substring-from-a-sas-string/">Deleting a substring from a SAS string</a></li>
<li><a href="https://blogs.sas.com/content/sgf/2020/11/04/removing-repeated-characters-in-sas-strings/">Removing repeated characters in SAS strings</a></li>
</ul>
<h2><strong>Questions? Thoughts? Comments?</strong></h2>
<p>Do you find this post useful? Please share your thoughts with us below.</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/14/introducing-trims-function-to-remove-any-leading-and-or-trailing-characters-from-sas-strings/">Introducing TRIMS function to remove any leading and/or trailing characters from SAS strings</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=rrJh79cui6w:wpc1gL56uDs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=rrJh79cui6w:wpc1gL56uDs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=rrJh79cui6w:wpc1gL56uDs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=rrJh79cui6w:wpc1gL56uDs:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=rrJh79cui6w:wpc1gL56uDs:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=rrJh79cui6w:wpc1gL56uDs:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=rrJh79cui6w:wpc1gL56uDs:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=rrJh79cui6w:wpc1gL56uDs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=rrJh79cui6w:wpc1gL56uDs:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/10/14/introducing-trims-function-to-remove-any-leading-and-or-trailing-characters-from-sas-strings/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/10/trimming-left-and-right-150x150.jpg" />
	</item>
		<item>
		<title>Encrypting Data Using SAS</title>
		<link>https://blogs.sas.com/content/sgf/2021/10/13/encrypting-data-using-sas/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/10/13/encrypting-data-using-sas/#comments</comments>
		
		<dc:creator><![CDATA[Ron Cody]]></dc:creator>
		<pubDate>Wed, 13 Oct 2021 13:50:48 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[cipher]]></category>
		<category><![CDATA[encryption]]></category>
		<category><![CDATA[XOR operator]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=35688</guid>

					<description><![CDATA[<p>There are many reasons why you might want to encrypt data. I use a SAS program to encrypt a list of logon names and passwords. Before we get started describing how to encrypt data, let's discuss some basic concepts concerning encrypting and decrypting data. All computer data is stored as [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/13/encrypting-data-using-sas/">Encrypting Data Using SAS</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>There are many reasons why you might want to encrypt data. I use a SAS program to encrypt a list of logon names and passwords. Before we get started describing how to encrypt data, let's discuss some basic concepts concerning encrypting and decrypting data.</p>
<p>All computer data is stored as a series of 1s and 0s. For example, an uppercase A in ASCII is <strong>01000001</strong>. Many encrypting schemes use a <strong>key</strong> to transform plaintext into ciphertext. As an example, suppose your key is B (<strong>01000010</strong>).</p>
<p>I'm sure you remember the Boolean operators AND, NOT, and OR. If you perform an AND operator on A and B, the result is a 1 if both values are true (1) and false (0) otherwise. So, A AND B is 01000000. The OR operator results in a value of true if either A or B is true, or both A and B are true. Therefore, A OR B is 01000011. The operator that you might not be as familiar with is the exclusive OR (XOR) operator. This is similar to an OR operator except that if both A and B are true, the result is false. A XOR B is equal to 00000011. Why is this useful? An interesting property of the XOR operator is if you take the result and use the XOR operator again on the previous result, you get back to the original value.</p>
<p>The table below shows how the XOR operator works:</p>
<table>
<tbody>
<tr>
<td width="159">A</td>
<td width="25">0</td>
<td width="23">1</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">1</td>
</tr>
<tr>
<td width="159">B</td>
<td width="25">0</td>
<td width="23">1</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">1</td>
<td width="24">0</td>
</tr>
<tr>
<td width="159">A XOR B</td>
<td width="25">0</td>
<td width="23">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">1</td>
<td width="24">1</td>
</tr>
<tr>
<td width="159">(A XOR B) XOR B</td>
<td width="25">0</td>
<td width="23">1</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">0</td>
<td width="24">1</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>If A is the cleartext message and B is the key, A XOR B is the ciphertext. If you perform an exclusive OR with the key (B) and the ciphertext (as was done in the last line), you get back the cleartext value (A).</p>
<p>Of course, you don't use single letter keys to encode messages. Key lengths of 8, 16, or even up to 512 are common. The problem with any key is that if you apply it to a long message, there is a pattern in the ciphertext that allows a code breaker to figure out how long the key is, and even what it is. There are several computer programs that can decode many of the popular encrypting methods. My favorite is:</p>
<p><a href="https://www.geocachingtoolbox.com/">https://www.geocachingtoolbox.com/</a></p>
<p>Here is a list of ciphers that can be broken with this program:</p>
<table>
<tbody>
<tr>
<td width="208">ADFGX/ADFGVX cipher</td>
<td width="208">Four-square cipher</td>
<td width="208">Substitution cipher</td>
</tr>
<tr>
<td width="208">Affine cipher</td>
<td width="208">Gronsfeld cipher</td>
<td width="208">Trifid cipher</td>
</tr>
<tr>
<td width="208">Atbash cipher</td>
<td width="208">Kamasutra cipher</td>
<td width="208">Vanity code</td>
</tr>
<tr>
<td width="208">Bacon cipher</td>
<td width="208">Kenny code</td>
<td width="208">Vigenère cipher</td>
</tr>
<tr>
<td width="208">Bifid cipher</td>
<td width="208">One-time pad</td>
<td width="208">Vigenère cipher decoder</td>
</tr>
<tr>
<td width="208">Burrows-Wheeler transform</td>
<td width="208">Playfair cipher</td>
<td width="208"></td>
</tr>
<tr>
<td width="208">Caeser cipher (ROT13)</td>
<td width="208">Rail Fence cipher</td>
<td width="208"></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Let's write a short SAS program that uses a <strong>key</strong> to encode a text string.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">data</span> Encode;
&nbsp;
<span style="color: #0000ff;">retain</span> <span style="color: #0000ff;">Key</span> <span style="color: #2e8b57; font-weight: bold;">12345</span>; ❶
&nbsp;
<span style="color: #0000ff;">length</span> Letter $ <span style="color: #2e8b57; font-weight: bold;">1</span>; ❷
&nbsp;
String = <span style="color: #a020f0;">'This is a test'</span>;
&nbsp;
<span style="color: #0000ff;">do</span> i = <span style="color: #2e8b57; font-weight: bold;">1</span> to lengthn<span style="color: #66cc66;">&#40;</span>String<span style="color: #66cc66;">&#41;</span>;
&nbsp;
Letter = <span style="color: #0000ff;">substr</span><span style="color: #66cc66;">&#40;</span>String,i,<span style="color: #2e8b57; font-weight: bold;">1</span><span style="color: #66cc66;">&#41;</span>; ❸
&nbsp;
<span style="color: #0000ff;">Rank</span> = <span style="color: #0000ff;">rank</span><span style="color: #66cc66;">&#40;</span>Letter<span style="color: #66cc66;">&#41;</span>; ❹
&nbsp;
Coded = <span style="color: #0000ff;">bxor</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">Rank</span>,<span style="color: #0000ff;">Key</span><span style="color: #66cc66;">&#41;</span>; ❺
&nbsp;
Decoded = <span style="color: #0000ff;">bxor</span><span style="color: #66cc66;">&#40;</span>Coded,<span style="color: #0000ff;">Key</span><span style="color: #66cc66;">&#41;</span>; ❻
&nbsp;
Clear = <span style="color: #0000ff;">byte</span><span style="color: #66cc66;">&#40;</span>Decoded<span style="color: #66cc66;">&#41;</span>; ❼
&nbsp;
<span style="color: #0000ff;">output</span>;
&nbsp;
<span style="color: #0000ff;">end</span>;
&nbsp;
<span style="color: #0000ff;">drop</span> i;
&nbsp;
<span style="color: #000080; font-weight: bold;">run</span>;
&nbsp;
 
&nbsp;
<span style="color: #0000ff;">title</span> <span style="color: #a020f0;">&quot;Listing of Data Set Encode&quot;</span>;
&nbsp;
<span style="color: #000080; font-weight: bold;">proc print</span> dta=Encode noobs;
&nbsp;
<span style="color: #0000ff;">var</span> Letter <span style="color: #0000ff;">Key</span> <span style="color: #0000ff;">Rank</span> Coded Decoded Clear;
&nbsp;
<span style="color: #0000ff;">format</span> <span style="color: #0000ff;">Key</span> <span style="color: #0000ff;">Rank</span> Coded binary8.;
&nbsp;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>❶ A RETAIN statement is used to assign the number 12345 to a numeric variable called Key.  (You could have used an assignment statement, but using a RETAIN statement is more efficient and elegant.</p>
<p>❷ The variable Letter will hold each letter of the message and is set to a length of one.</p>
<p>❸ The SUBSTR function will extract each letter from String.</p>
<p>❹ Because Boolean operators only operate on true/false values, you use the RANK function to convert each letter to its ASCII value (stored internally as a series of 0s and 1s).</p>
<p>❺ You now use the BXOR (binary exclusive OR) function to encode each letter of your message.</p>
<p>❻ To demonstrate that the program is working, you use the BXOR function again to demonstrate that this process will return the original String.</p>
<p>❼ The BYTE function takes an ASCII value and returns the appropriate character.</p>
<p>Here is the listing of data set Encode:</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt1.png"><img loading="lazy" class="alignnone size-medium wp-image-35691" src="https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt1-251x300.png" alt="" width="251" height="300" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt1-251x300.png 251w, https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt1-858x1024.png 858w, https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt1-768x916.png 768w, https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt1.png 954w" sizes="(max-width: 251px) 100vw, 251px" /></a></p>
<p>Because this encryption method uses a single (and short) key, it would be fairly easy to break. What if you encode every letter of the original message with a <strong>different</strong> key? You can accomplish this by using the SAS random function RAND and using a seed value so that the same series of random numbers gets generated every time you run the program. You can even use one of a dozen different random distributions, to make it harder for someone to decode your file. Here is an example:</p>
<p>First, here is a copy of my text file that contains my secret message (stored in the location c:\Books\Blogs\Cipher\Clear_Text.txt).</p>
<blockquote style="border: 2px solid #666;padding: 10px;background-color: #ccc"><p>Good morning Mr. Phelps.</p>
<p>Your mission, should you decide to accept it,</p>
<p>is to rid the world of evil.</p>
<p>As usual, if you or any member of your team are caught or killed,</p>
<p>the Secretary will disavow any knowledge of your actions.</p></blockquote>
<p>The following program encrypts this file and creates a temporary data set (in a real situation, you would make this a permanent data set):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">data</span> Coded;
&nbsp;
<span style="color: #0000ff;">call</span> streaminit<span style="color: #66cc66;">&#40;</span><span style="color: #2e8b57; font-weight: bold;">13579</span><span style="color: #66cc66;">&#41;</span>; ❶
&nbsp;
<span style="color: #0000ff;">array</span> l<span style="color: #66cc66;">&#91;</span><span style="color: #2e8b57; font-weight: bold;">150</span><span style="color: #66cc66;">&#93;</span> $ <span style="color: #2e8b57; font-weight: bold;">1</span> _temporary_; ❷
&nbsp;
<span style="color: #0000ff;">array</span> num<span style="color: #66cc66;">&#91;</span><span style="color: #2e8b57; font-weight: bold;">150</span><span style="color: #66cc66;">&#93;</span> _temporary_; ❸
&nbsp;
<span style="color: #0000ff;">array</span> xor<span style="color: #66cc66;">&#91;</span><span style="color: #2e8b57; font-weight: bold;">150</span><span style="color: #66cc66;">&#93;</span>; ❹
&nbsp;
<span style="color: #0000ff;">infile</span> <span style="color: #a020f0;">&quot;c:<span style="color: #000099; font-weight: bold;">\B</span>ooks<span style="color: #000099; font-weight: bold;">\B</span>logs<span style="color: #000099; font-weight: bold;">\C</span>ipher<span style="color: #000099; font-weight: bold;">\C</span>lear_Text.txt&quot;</span> pad;
&nbsp;
<span style="color: #0000ff;">input</span> string $150.; ❺
&nbsp;
<span style="color: #0000ff;">do</span> i = <span style="color: #2e8b57; font-weight: bold;">1</span> to <span style="color: #0000ff;">dim</span><span style="color: #66cc66;">&#40;</span>l<span style="color: #66cc66;">&#41;</span>;
&nbsp;
l<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> = <span style="color: #0000ff;">substr</span><span style="color: #66cc66;">&#40;</span>string,i,<span style="color: #2e8b57; font-weight: bold;">1</span><span style="color: #66cc66;">&#41;</span>; ❼
&nbsp;
num<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> = <span style="color: #0000ff;">rank</span><span style="color: #66cc66;">&#40;</span>l<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>; ❽
&nbsp;
xor<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> = <span style="color: #0000ff;">bxor</span><span style="color: #66cc66;">&#40;</span>num<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>,<span style="color: #0000ff;">int</span><span style="color: #66cc66;">&#40;</span><span style="color: #2e8b57; font-weight: bold;">100</span><span style="color: #006400; font-style: italic;">*rand('Uniform')));</span> ❾
&nbsp;
<span style="color: #0000ff;">end</span>;
&nbsp;
<span style="color: #0000ff;">keep</span> xor1-xor150;
&nbsp;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>❶ You need to set a seed value using CALL STREAMINIT so that when you run the decoding program, you will generate the same series of random numbers.</p>
<p>❷ This temporary array will hold up to 150 characters.</p>
<p>❸ The Num array holds the numerical ASCII value for each of the characters in the line.</p>
<p>❹ The XOR array holds the values of the exclusive OR between each numerical ASCII value and the Key.</p>
<p>❺ Read in a string of up to 150 characters.</p>
<p>❻ The DO LOOP picks up each character in a line, starting from 1 and ending at the length of each line.</p>
<p>❼ The RANK function outputs the ASCII value of each character.</p>
<p>❽ The BXOR (binary exclusive OR) function performs the exclusive OR between each ASCII value and the Key.</p>
<p>To decode this message, use the following program:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">data</span> Decode;
&nbsp;
<span style="color: #0000ff;">call</span> streaminit<span style="color: #66cc66;">&#40;</span><span style="color: #2e8b57; font-weight: bold;">13579</span><span style="color: #66cc66;">&#41;</span>; ❶
&nbsp;
<span style="color: #0000ff;">array</span> l<span style="color: #66cc66;">&#91;</span><span style="color: #2e8b57; font-weight: bold;">150</span><span style="color: #66cc66;">&#93;</span> $ <span style="color: #2e8b57; font-weight: bold;">1</span> _temporary_;
&nbsp;
<span style="color: #0000ff;">array</span> num<span style="color: #66cc66;">&#91;</span><span style="color: #2e8b57; font-weight: bold;">150</span><span style="color: #66cc66;">&#93;</span> _temporary_;
&nbsp;
<span style="color: #0000ff;">array</span> xor<span style="color: #66cc66;">&#91;</span><span style="color: #2e8b57; font-weight: bold;">150</span><span style="color: #66cc66;">&#93;</span>;
&nbsp;
<span style="color: #0000ff;">length</span> String $ <span style="color: #2e8b57; font-weight: bold;">150</span>;
&nbsp;
<span style="color: #0000ff;">set</span> Coded;
&nbsp;
<span style="color: #0000ff;">do</span> i = <span style="color: #2e8b57; font-weight: bold;">1</span> to <span style="color: #0000ff;">dim</span><span style="color: #66cc66;">&#40;</span>l<span style="color: #66cc66;">&#41;</span>;
&nbsp;
num<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> = <span style="color: #0000ff;">bxor</span><span style="color: #66cc66;">&#40;</span>xor<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>,<span style="color: #0000ff;">int</span><span style="color: #66cc66;">&#40;</span><span style="color: #2e8b57; font-weight: bold;">100</span><span style="color: #006400; font-style: italic;">*rand('Uniform')));</span> ❷
&nbsp;
l<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> = <span style="color: #0000ff;">byte</span><span style="color: #66cc66;">&#40;</span>num<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>; ❸
&nbsp;
<span style="color: #0000ff;">substr</span><span style="color: #66cc66;">&#40;</span>String,i,<span style="color: #2e8b57; font-weight: bold;">1</span><span style="color: #66cc66;">&#41;</span> = l<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>; ❹
&nbsp;
<span style="color: #0000ff;">end</span>;
&nbsp;
<span style="color: #0000ff;">keep</span> String;
&nbsp;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p>❶ Notice that the value of the CALL STREAMINIT routine uses the same seed as the previous program.</p>
<p>❷ The BXOR function between each coded value and the Key, will produce the cleartext.</p>
<p>❸ The BYTE function will convert the ASCII values back to letters, numbers, and other characters.</p>
<p>❹ Finally, the SUBSTR function used on the left-hand side of the equal sign will place each of the characters into the appropriate location in the String variable. (See my previous blog that discusses the use of the SUBSTR function used on the left-hand side of the equal sign.)</p>
<p>Here is the output:</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt2.png"><img loading="lazy" class="alignnone size-medium wp-image-35694" src="https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt2-300x156.png" alt="" width="300" height="156" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt2-300x156.png 300w, https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt2-768x400.png 768w, https://blogs.sas.com/content/sgf/files/2021/10/Codyencrypt2.png 1010w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>It would be straightforward to convert these two programs into macros so that you could encrypt and decrypt any file.</p>
<p>Of course, I would be remiss if I didn't mention that you can encrypt a SAS data set using two data set options ENCRYPT=and ENCRYPTKEY="password". But what would be the fun of that?</p>
<p>Here is an example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #006400; font-style: italic;">*Note: AES stands for Advanced Encryption Standard
&nbsp;
If you use quotation marks on the ENCRYPTKEY= option, you have
&nbsp;
more flexibility in choosing a password (maximum length=64);</span>
&nbsp;
 
&nbsp;
<span style="color: #000080; font-weight: bold;">data</span> Secret<span style="color: #66cc66;">&#40;</span>encrypt=aes encryptkey=<span style="color: #a020f0;">&quot;mypassword&quot;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #0000ff;">input</span> String $80.;
&nbsp;
datalines;
&nbsp;
This is a secret <span style="color: #0000ff;">message</span>.
&nbsp;
See <span style="color: #0000ff;">if</span> you can decode it.
&nbsp;
This <span style="color: #0000ff;">message</span> will <span style="color: #0000ff;">not</span> self-destruct!
&nbsp;
;</pre></td></tr></table></div>

<p>You can decode the encrypted data set by including the DATA set option ENCRYPTKEY="password" in any procedure, such as the PROC PRINT shown below:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #0000ff;">title</span> <span style="color: #a020f0;">&quot;Listing of Data Set Secret&quot;</span>;
&nbsp;
<span style="color: #000080; font-weight: bold;">proc print</span> <span style="color: #000080; font-weight: bold;">data</span>=Secret<span style="color: #66cc66;">&#40;</span>encryptkey=<span style="color: #a020f0;">&quot;mypassword&quot;</span><span style="color: #66cc66;">&#41;</span> noobs;
&nbsp;
<span style="color: #000080; font-weight: bold;">run</span>;</pre></td></tr></table></div>

<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/13/encrypting-data-using-sas/">Encrypting Data Using SAS</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=W_aZo7TlqMc:dsMiKLNQT-M:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=W_aZo7TlqMc:dsMiKLNQT-M:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=W_aZo7TlqMc:dsMiKLNQT-M:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=W_aZo7TlqMc:dsMiKLNQT-M:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=W_aZo7TlqMc:dsMiKLNQT-M:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=W_aZo7TlqMc:dsMiKLNQT-M:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=W_aZo7TlqMc:dsMiKLNQT-M:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=W_aZo7TlqMc:dsMiKLNQT-M:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=W_aZo7TlqMc:dsMiKLNQT-M:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/10/13/encrypting-data-using-sas/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/10/461990699-150x150.jpg" />
	</item>
		<item>
		<title>Your guide for analyzing real time data with streaming analytics from SAS® Viya® on Azure</title>
		<link>https://blogs.sas.com/content/sgf/2021/10/12/your-guide-for-analyzing-real-time-data-with-streaming-analytics-from-sas-viya-on-azure/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/10/12/your-guide-for-analyzing-real-time-data-with-streaming-analytics-from-sas-viya-on-azure/#respond</comments>
		
		<dc:creator><![CDATA[Nick Johnson]]></dc:creator>
		<pubDate>Tue, 12 Oct 2021 13:30:44 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[SAS Viya]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=35607</guid>

					<description><![CDATA[<p>This article was co-written by Jane Howell, IoT Product Marketing Leader at SAS. Check out her blog profile for more information. As artificial intelligence comes of age and data continues to disrupt traditional industry boundaries, the need for real-time analytics is escalating as organizations fight to keep their competitive edge. [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/12/your-guide-for-analyzing-real-time-data-with-streaming-analytics-from-sas-viya-on-azure/">Your guide for analyzing real time data with streaming analytics from SAS® Viya® on Azure</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><em>This article was co-written by <a href="https://www.linkedin.com/in/janehowell/">Jane Howell</a>, IoT Product Marketing Leader at SAS. Check out her <a href="https://blogs.sas.com/content/author/janehowell/">blog profile</a> for more information.</em></p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/compass-4891499_1280.jpg"><img loading="lazy" src="https://blogs.sas.com/content/sgf/files/2021/10/compass-4891499_1280-1024x654.jpg" alt="" width="402" height="148" class="alignleft size-large wp-image-35610" /></a></p>
<p>As artificial intelligence comes of age and data continues to disrupt traditional industry boundaries, the need for real-time analytics is escalating as organizations fight to keep their competitive edge. The benefits of real-time analytics are significant. Manufacturers must inspect thousands of products per minute for defects. Utilities need to eliminate unplanned downtime to keep the lights on and protect workers. And governments need to warn citizens of natural disasters, like flooding events, providing real time updates to save lives and protect property.</p>
<p>Each of these use cases requires a complex network of IoT sensors, edge computing, and machine learning models that can adapt and improve by ingesting and analyzing a diverse set of high-volume, high-velocity data.</p>
<p><a href="https://www.sas.com/en_us/solutions/cloud/microsoft-azure.html">SAS and Microsoft are partnering</a> to inspire greater trust and confidence in every decision, by innovating with proven AI and streaming analytics in the cloud and on the edge. Together, we make it easier for companies to harness hidden insights in their diverse, high volume, high velocity IoT data, and capitalize on those insights in Microsoft Azure for secure, fast, and reliable decision making. </p>
<p>To take advantage of all the benefits that real-time streaming analytics has to offer, it’s important to tailor your streaming environment to your organization’s specific needs. Below, we’ll dive into how to understand the value of IoT in parallel to your organization’s business objectives and then strategize, plan, and manage your streaming analytics environment with SAS Viya on Azure. </p>
<h3>Step 1: Understand the value of IoT</h3>
<p>While you may already know that IoT and streaming analytics are the right technologies to enable your business’ real time analytics strategy, it is important to understand how it works and how you can benefit. You can think of streaming analytics for IoT in three distinct parts: <strong>sense</strong>, <strong>understand </strong>and <strong>act</strong>. </p>
<p>•	<strong>Sense</strong>: Sensors by design are distributed, numerous, and collect data at high fidelity in various formats. The majority of data collected by sensors has a short useful life and requires immediate action. Streaming analytics is well-suited to this distributed sensor environment to collect data for analysis.<br />
•	<strong>Understand</strong>: A significant number of IoT use cases requires quick decision-making in real time or near-real time. To achieve this, we need to apply analytics to data in motion. This can be done by deploying AI models that detect anomalies and patterns as events occur.<br />
•	<strong>Act</strong>: As with any analytics-based decision support, it is critical to act on the insight generated. Once a pattern is detected this must trigger an action to reach a desired outcome. This could be to alert key individuals or change the state of a device, possibly eliminating the need for any human intervention.</p>
<p>The value in IoT is driven by the reduced latency to trigger the desired outcome. Maybe that’s improving production quality in the manufacturing process, recommending a new product to a customer as they shop online, or eliminating equipment failures in a utility plant. Whatever it is, time is of the essence and IoT can help get you there.</p>
<h3>Step 2: Strategize</h3>
<p>Keeping the “sense, understand, act” framework in mind, the next step is to outline what you hope to achieve. To get the most out of your streaming analytics with SAS and Microsoft, keep your objectives in mind so you can stay focused on the business outcome instead of trying to act on every possible data point. </p>
<p>Some important questions to ask yourself are: </p>
<p>1.	What is the primary and secondary outcomes you are hoping to achieve? Increase productivity? Augment safety? Improve customer satisfaction?<br />
2.	What patterns or events of interest do you want to observe?<br />
3.	If your machines and sensors show anomalous behavior what actions need to be taken? Is there an existing business process that reflects this?<br />
4.	What data is important to be stored as historical data and what data can expire?<br />
5.	What kind of infrastructure exists from the point where data is generated (edge) to cloud? Is edge processing an option for time-critical use cases or does processing needs to be centralized in cloud?<br />
6.	What are your analytics and application development platforms? Do you have access to high performance streaming analytics and cloud infrastructure to support this strategy?</p>
<p>Once you’ve identified your outcomes, define which metrics and KPIs you can measure to show impact. Make sure to have some baseline metrics to start from that you can improve upon.</p>
<h3>Step 3: Plan and adopt</h3>
<p>Now it’s time to take your strategy and plan the adoption of streaming analytics across your business.</p>
<p>Adoption will look different if you already have an IoT platform in place or if you are working to create a net-new solution. If you are going to be updating or iterating upon an <strong>existing solution</strong>, you will want to make sure you have access to key historical data to measure improvement and use institutional knowledge to maximize performance. If you are working with a <strong>net-new solution</strong>, you will want to give yourself some additional time to start small and then scale your operations up over time so you can tackle any unforeseen challenges. </p>
<p>In both cases it is important to have key processes aligned to the following considerations:</p>
<p>•	<strong>Data variety, volume and accuracy</strong>: Focus here on the “sense” part of the “sense, understand, act” framework. Accessing good data is the foundation to the success of your streaming projects. Make sure you have the right data needed to achieve your desired business outcome. Streaming analytics helps you understand the signals in IoT data, so you can make better decisions. But if you can’t access the right data, or your data is not clean, your project will not be successful. Know how much data you will be processing and where. Data can be noisy, so it is important to understand which data will give you the most insight.<br />
•	<strong>Reliability</strong>: Ensure events are only processed once so you’re not observing the same events multiple times. When equipment fails or defects occur on the production line, ensure there are processes in place to auto-start to maximize uptime for operations.<br />
•	<strong>Scalability</strong>: Data science resources are scarce, so choose a low-code, no-code solution that can address your need to scale.  When volume increases, how are you going to scale up and out? Azure simplifies scale with its PaaS offerings, including the ability to auto-scale SAS Viya on Azure.<br />
•	<strong>Operations</strong>: Understand how you plan to deploy your streaming analytics models, govern them and decide which processes can be automated to save time.<br />
•	<strong>Choose the right partners and tools</strong>: This is critical to the success of any initiative. SAS and Microsoft provide a best-in-class solution for bringing streaming analytics on the most advanced platform for integrated cloud and edge analytics. </p>
<p>Now that you have created your plan, it is time to adopt. Remember to start small and add layers of capability over time. </p>
<h3>Step 4: Manage</h3>
<p>To get the most value from IoT and streaming analytics, organizations must implement processes for continuous iteration, development, and improvement. That means having the flexibility to choose the most powerful models for your needs – using SAS, Azure cloud services, or open source. It also means simplifying DevOps processes for deploying and monitoring your streaming analytics to maximize uptime for your business systems. </p>
<p>With SAS Viya on Azure, it is easy to do this and more. Seamlessly move between your SAS and Microsoft environment with single sign on authentication. Develop models with a host of no-code, low-code tools, and monitor the performance of your SAS and open-source models from a single model management library.</p>
<p>Maximizing value from your IoT and streaming analytics systems is a continuous, agile process. That is why it is critical to choose the most performant platform for your infrastructure and analytics needs. Together, SAS and Microsoft make it easier for organizations of all sizes and maturity to rapidly build, deploy, and scale IoT and streaming analytics, maximizing up time to better serve customers, employees, and citizens.</p>
<p>If you want to learn more about SAS and streaming analytics and IoT capabilities as well as our partnership with Microsoft, check out the resources below:</p>
<p>•	Learn about SAS Viya’s <a href="https://www.sas.com/esp">IoT and streaming analytics capabilities</a><br />
•	Discover out all the exciting things SAS and Microsoft are working to achieve together at <a href="https://www.sas.com/en_us/solutions/cloud/microsoft-azure.html">SAS.com/Microsoft</a><br />
•	See how SAS and Microsoft work together to help the town of Cary, North Carolina warn citizens of flood events: <a href="https://www.sas.com/en_us/customers/townofcary-flood-prediction.html">Smart city uses analytics and IoT to predict and manage flood events</a></p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/12/your-guide-for-analyzing-real-time-data-with-streaming-analytics-from-sas-viya-on-azure/">Your guide for analyzing real time data with streaming analytics from SAS® Viya® on Azure</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=qhZBJOT8hf8:Qf5NRsVZmhw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=qhZBJOT8hf8:Qf5NRsVZmhw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=qhZBJOT8hf8:Qf5NRsVZmhw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=qhZBJOT8hf8:Qf5NRsVZmhw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=qhZBJOT8hf8:Qf5NRsVZmhw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=qhZBJOT8hf8:Qf5NRsVZmhw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=qhZBJOT8hf8:Qf5NRsVZmhw:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=qhZBJOT8hf8:Qf5NRsVZmhw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=qhZBJOT8hf8:Qf5NRsVZmhw:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/10/12/your-guide-for-analyzing-real-time-data-with-streaming-analytics-from-sas-viya-on-azure/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/10/compass-4891499_1280-150x150.jpg" />
	</item>
		<item>
		<title>CAS-Action! Executing the SAS DATA Step in SAS Viya</title>
		<link>https://blogs.sas.com/content/sgf/2021/10/08/cas-action-executing-the-sas-data-step-in-sas-viya/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/10/08/cas-action-executing-the-sas-data-step-in-sas-viya/#respond</comments>
		
		<dc:creator><![CDATA[Peter Styliadis]]></dc:creator>
		<pubDate>Fri, 08 Oct 2021 18:01:47 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[big data]]></category>
		<category><![CDATA[CAS]]></category>
		<category><![CDATA[CAS Action Sets]]></category>
		<category><![CDATA[CAS Actions]]></category>
		<category><![CDATA[CASL]]></category>
		<category><![CDATA[data step]]></category>
		<category><![CDATA[Data step programmers]]></category>
		<category><![CDATA[Developer]]></category>
		<category><![CDATA[Developers]]></category>
		<category><![CDATA[Programming Tips]]></category>
		<category><![CDATA[runCode action]]></category>
		<category><![CDATA[SAS Viya]]></category>
		<category><![CDATA[SAS Viya Programming]]></category>
		<category><![CDATA[tips & techniques]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=35547</guid>

					<description><![CDATA[<p>Just because you are using CAS actions doesn't mean you can forget about the powerful SAS DATA step. The dataStep.runCode CAS action is here! Welcome back to my SAS Users blog series CAS Action! - a series on fundamentals. I've broken the series into logical, consumable parts. If you'd like [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/08/cas-action-executing-the-sas-data-step-in-sas-viya/">CAS-Action! Executing the SAS DATA Step in SAS Viya</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Just because you are using CAS actions doesn't mean you can forget about the powerful SAS DATA step. The <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/caspg/cas-datastep-runcode.htm">dataStep.runCode</a> CAS action is here!</p>
<p>Welcome back to my <a href="https://blogs.sas.com/content/sgf/2021/08/06/cas-action-a-series-on-fundamentals/">SAS Users blog series CAS Action! - a series on fundamentals</a>. I've broken the series into logical, consumable parts. If you'd like to start by learning a little more about what CAS Actions are, please see <a href="https://blogs.sas.com/content/sgf/2021/08/06/cas-actions-and-action-sets-a-brief-intro/">CAS Actions and Action Sets - a brief intro</a>. Or if you'd like to see other topics in the series, see the <a href="https://blogs.sas.com/content/sgf/2021/08/06/cas-action-a-series-on-fundamentals/">overview page</a>.</p>
<p>In this example, I will use the CAS procedure to execute the <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/caspg/cas-datastep-runcode.htm">dataStep.runCode</a> CAS action. Be aware, instead of using the CAS procedure, I could execute the action with Python, R, or even a REST API with some slight changes to the syntax for the specific language.</p>
<h2>Why use the DATA Step?</h2>
<p>It's pretty simple, the DATA step is a powerful way to process your data. It gives you full control of each row and column, ability to easily create multiple output tables, and provides a variety of statements to pretty much do anything you need.</p>
<p>In this example, I will use the DATA step to quickly create three CAS tables based on the value of a column.  Before we execute the DATA step, let's view the frequency values of the <strong>Origin</strong> column in the <strong>cars</strong> table. To do that, I'll use the simple.freq action.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">proc cas</span>;
    simple.freq / 
          <span style="color: #0000ff;">table</span>=<span style="color: #66cc66;">&#123;</span>name=<span style="color: #a020f0;">'cars'</span>, caslib=<span style="color: #a020f0;">'casuser'</span><span style="color: #66cc66;">&#125;</span>,
           <span style="color: #0000ff;">input</span>=<span style="color: #a020f0;">'Origin'</span>;
<span style="color: #000080; font-weight: bold;">quit</span>;</pre></td></tr></table></div>

<h2><a href="https://blogs.sas.com/content/sgf/files/2021/10/simplefreq-action.png"><img loading="lazy" class="alignnone size-full wp-image-35550" src="https://blogs.sas.com/content/sgf/files/2021/10/simplefreq-action.png" alt="" width="380" height="189" srcset="https://blogs.sas.com/content/sgf/files/2021/10/simplefreq-action.png 380w, https://blogs.sas.com/content/sgf/files/2021/10/simplefreq-action-300x149.png 300w, https://blogs.sas.com/content/sgf/files/2021/10/simplefreq-action-164x82.png 164w" sizes="(max-width: 380px) 100vw, 380px" /></a></h2>
<p>The result of the freq action shows that the <strong>Origin</strong> column in the <strong>cars</strong> CAS table has three distinct values: <em>Asia</em>, <em>Europe</em> and <em>USA</em>. I can use that information to create three CAS tables based off these unique values using the SAS DATA step.</p>
<h2>Execute DATA Step in SAS Viya's CAS Server</h2>
<p>One way to execute the DATA step directly in CAS is to use the <strong>runCode</strong> action with the <b>code </b>parameter. In the <strong>code</strong> parameter just specify the DATA step as a string. That's it!</p>
<p>In this example, I'll add the DATA step within a SOURCE block. The SOURCE block stores the code as variable. The DATA step code is stored in the variable <strong>originTables</strong>. This DATA step will create three CAS tables, one table for each unique value of the <strong>Origin</strong> column in the <strong>cars</strong> table.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">proc cas</span>;
    source originTables;
        <span style="color: #000080; font-weight: bold;">data</span> casuser.Asia
             casuser.Europe
             casuser.USA;
            <span style="color: #0000ff;">set</span> casuser.cars;
            <span style="color: #0000ff;">if</span> Origin=<span style="color: #a020f0;">'Asia'</span> <span style="color: #0000ff;">then</span> <span style="color: #0000ff;">output</span> casuser.Asia;
            <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> Origin=<span style="color: #a020f0;">'Europe'</span> <span style="color: #0000ff;">then</span> <span style="color: #0000ff;">output</span> casuser.Europe;
            <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> Origin=<span style="color: #a020f0;">'USA'</span> <span style="color: #0000ff;">then</span> <span style="color: #0000ff;">output</span> casuser.USA;
        <span style="color: #000080; font-weight: bold;">run</span>;
    endsource;
&nbsp;
    dataStep.runCode / code=originTables;
<span style="color: #000080; font-weight: bold;">quit</span>;</pre></td></tr></table></div>

<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/runCode-Action-SAS-Viya.png"><img loading="lazy" class="alignnone size-full wp-image-35553" src="https://blogs.sas.com/content/sgf/files/2021/10/runCode-Action-SAS-Viya.png" alt="" width="668" height="300" srcset="https://blogs.sas.com/content/sgf/files/2021/10/runCode-Action-SAS-Viya.png 668w, https://blogs.sas.com/content/sgf/files/2021/10/runCode-Action-SAS-Viya-300x135.png 300w" sizes="(max-width: 668px) 100vw, 668px" /></a></p>
<p>The <b>runCode </b>action executes the DATA step in the distributed CAS environment and returns information about the input and output tables. Notice three CAS tables were created: <strong>Asia</strong>, <strong>Europe</strong> and <strong>USA</strong>.</p>
<h2>DATA Step in CAS has Limitations</h2>
<p>Now, one thing to be aware of is not all functionality of the DATA step is available in CAS. If you are using the runCode action with an unsupported statement or function in CAS, you will receive an error. Let's look at an example using the first function, which gets the first letter of a string, and is not supported in CAS.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">proc cas</span>;
    source originTables;
        <span style="color: #000080; font-weight: bold;">data</span> casuser.bad;
            <span style="color: #0000ff;">set</span> casuser.cars;
            NewCol=first<span style="color: #66cc66;">&#40;</span>Model<span style="color: #66cc66;">&#41;</span>;
        <span style="color: #000080; font-weight: bold;">run</span>;
    endsource;
    dataStep.runCode / code=originTables;
<span style="color: #000080; font-weight: bold;">quit</span>;</pre></td></tr></table></div>

<p>&nbsp;</p>
<p><a href="https://blogs.sas.com/content/sgf/files/2021/10/Not-Suported-in-CAS.png"><img loading="lazy" class="alignnone size-full wp-image-35571" src="https://blogs.sas.com/content/sgf/files/2021/10/Not-Suported-in-CAS.png" alt="" width="642" height="131" srcset="https://blogs.sas.com/content/sgf/files/2021/10/Not-Suported-in-CAS.png 642w, https://blogs.sas.com/content/sgf/files/2021/10/Not-Suported-in-CAS-300x61.png 300w" sizes="(max-width: 642px) 100vw, 642px" /></a></p>
<p>The results of the runCode action return an error. The error occurs because the FIRST function is unknown or cannot be accessed. In situations like this you will need to find a CAS supported method to complete the task. (HINT: Here instead of the first function you can use the substr function).</p>
<p>For more information visit <a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/casdspgm/p1eyivn5kal7qwn1drrdt71v21ml.htm?homeOnFail">Restrictions and Supported Language Elements</a>. Be sure to find the version of your SAS Viya environment.</p>
<h2>Summary</h2>
<p>In SAS Viya, the runCode action provides an easy way to execute most of the traditional DATA step in CAS in any language, from the CAS Language (CASL), to Python, R, Lua, Java and more.</p>
<h3>Additional Resources</h3>
<p><a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/caspg/cas-datastep-runcode.htm" target="_blank" rel="noopener noreferrer">runCode Action</a><br />
<a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/caspg/n0vsh1uy8gxjodn1p4zg9iw3jwfa.htm" target="_blank" rel="noopener noreferrer">DATA Step Action Set: Details</a><br />
<a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/casdspgm/p1eyivn5kal7qwn1drrdt71v21ml.htm?homeOnFail" target="_blank" rel="noopener noreferrer">Restrictions and Supported Language Elements</a><br />
<a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_014/proccas/p1nh54k4wc2sgyn1g66ietjwmwsn.htm" target="_blank" rel="noopener noreferrer">SOURCE statement</a><br />
<a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_012/grstatproc/p0tngvy99l0bgdn10xabchb6kqtr.htm?homeOnFail" target="_blank" rel="noopener noreferrer">SAS® Cloud Analytic Services: Fundamentals</a><br />
<a href="https://blogs.sas.com/content/sgf/files/2021/10/DATAstep.txt" target="_blank" rel="noopener noreferrer">Code</a></p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/10/08/cas-action-executing-the-sas-data-step-in-sas-viya/">CAS-Action! Executing the SAS DATA Step in SAS Viya</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=1nHQbZROM_Q:xX9SknFOGCw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=1nHQbZROM_Q:xX9SknFOGCw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=1nHQbZROM_Q:xX9SknFOGCw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=1nHQbZROM_Q:xX9SknFOGCw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=1nHQbZROM_Q:xX9SknFOGCw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=1nHQbZROM_Q:xX9SknFOGCw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=1nHQbZROM_Q:xX9SknFOGCw:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=1nHQbZROM_Q:xX9SknFOGCw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=1nHQbZROM_Q:xX9SknFOGCw:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/10/08/cas-action-executing-the-sas-data-step-in-sas-viya/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/10/DATAStep-Action-150x150.jpg" />
	</item>
		<item>
		<title>Jedi SAS Tricks: 5 Ways to Make Your SAS Code Run Faster</title>
		<link>https://blogs.sas.com/content/sgf/2021/09/30/5-ways-to-make-your-sas-code-run-faster/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/09/30/5-ways-to-make-your-sas-code-run-faster/#respond</comments>
		
		<dc:creator><![CDATA[SAS Jedi]]></dc:creator>
		<pubDate>Thu, 30 Sep 2021 18:43:22 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[SAS Programmers]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[YouTube]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=35406</guid>

					<description><![CDATA[<p>Tired of waiting for answers? Then make your SAS code run faster with these 5 tips.</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/09/30/5-ways-to-make-your-sas-code-run-faster/">Jedi SAS Tricks: 5 Ways to Make Your SAS Code Run Faster</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I'll admit it - I'm often impatient while waiting for results, so my code needs to run as fast as possible! In this video, I show you how you can get faster results, too.</p>
<p><iframe title="SAS Tutorial | 5 Ways to Make Your SAS Code Run Faster" width="702" height="395" src="https://www.youtube.com/embed/he9ecikOPCE?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p>I'll demonstrate several different techniques that produce identical results, and compare processing speeds. For a more robust assessment, I'll test the techniques while reading from both SAS data sets and database tables. Analysis of the results clearly shows that when the techniques produce identical results, these choices usually produce faster run times:</p>
<ol>
<li>Use a WHERE statement instead of a subsetting IF statement.</li>
<li>Use the KEEP= dataset option on input data sets instead of a KEEP statement.</li>
<li>Should I use SQL or DATA step?
<ul>
<li>If producing a single result, use SQL.</li>
<li>If producing multiple results, use the DATA step.</li>
</ul>
</li>
<li>If your process is CPU bound:
<ul>
<li>If you have access to CAS, run it in CAS.</li>
<li>Otherwise, refactor in DS2.</li>
</ul>
</li>
</ol>
<p>The programs I used to create the video are available for <a href="https://bit.ly/5FastTipsCode1">download from GitHub</a> if you want to experiment.</p>
<p>Until next time, may the SAS be with you!<br />
Mark</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/09/30/5-ways-to-make-your-sas-code-run-faster/">Jedi SAS Tricks: 5 Ways to Make Your SAS Code Run Faster</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=0oT-t9mMPQE:bjPh6lXVRTc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=0oT-t9mMPQE:bjPh6lXVRTc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=0oT-t9mMPQE:bjPh6lXVRTc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=0oT-t9mMPQE:bjPh6lXVRTc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=0oT-t9mMPQE:bjPh6lXVRTc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=0oT-t9mMPQE:bjPh6lXVRTc:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=0oT-t9mMPQE:bjPh6lXVRTc:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=0oT-t9mMPQE:bjPh6lXVRTc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=0oT-t9mMPQE:bjPh6lXVRTc:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/09/30/5-ways-to-make-your-sas-code-run-faster/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/09/Thumbnail_MarkJordan-150x150.jpeg" />
	</item>
		<item>
		<title>CAS-Action! Executing SQL in SAS Viya</title>
		<link>https://blogs.sas.com/content/sgf/2021/09/28/cas-action-executing-sql-in-sas-viya/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/09/28/cas-action-executing-sql-in-sas-viya/#respond</comments>
		
		<dc:creator><![CDATA[Peter Styliadis]]></dc:creator>
		<pubDate>Tue, 28 Sep 2021 14:10:53 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[big data]]></category>
		<category><![CDATA[CAS]]></category>
		<category><![CDATA[CAS Action Sets]]></category>
		<category><![CDATA[CAS Actions]]></category>
		<category><![CDATA[CASL]]></category>
		<category><![CDATA[data exploration]]></category>
		<category><![CDATA[Developers]]></category>
		<category><![CDATA[fedSQL.execDirect]]></category>
		<category><![CDATA[Programming Tips]]></category>
		<category><![CDATA[SAS CAS REST APIs]]></category>
		<category><![CDATA[SAS Viya]]></category>
		<category><![CDATA[SAS Viya Programming]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[SQL in CAS]]></category>
		<category><![CDATA[tips and tricks]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=32199</guid>

					<description><![CDATA[<p>SQL is an important language for any programmer working with data. In SAS Cloud Analytic Services (CAS) you can execute SQL queries using the fedSQL.execDirect CAS action! Welcome back to my SAS Users blog series CAS Action! - a series on fundamentals. I've broken the series into logical, consumable parts. [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/09/28/cas-action-executing-sql-in-sas-viya/">CAS-Action! Executing SQL in SAS Viya</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>SQL is an important language for any programmer working with data. In SAS Cloud Analytic Services (CAS) you can execute SQL queries using the <strong>fedSQL.execDirect</strong> CAS action!</p>
<p>Welcome back to my <a href="https://blogs.sas.com/content/sgf/2021/08/06/cas-action-a-series-on-fundamentals/">SAS Users blog series CAS Action! - a series on fundamentals</a>. I've broken the series into logical, consumable parts. If you'd like to start by learning a little more about what CAS Actions are, please see <a href="https://blogs.sas.com/content/sgf/2021/08/06/cas-actions-and-action-sets-a-brief-intro/">CAS Actions and Action Sets - a brief intro</a>. Or if you'd like to see other topics in the series, see the <a href="https://blogs.sas.com/content/sgf/2021/08/06/cas-action-a-series-on-fundamentals/">overview page</a>.</p>
<p>In this example, I will use the CAS procedure to execute the <a href="https://documentation.sas.com/?cdcId=pgmsascdc&amp;cdcVersion=default&amp;docsetId=caspg&amp;docsetTarget=cas-fedsql-execdirect.htm"><b>execDirect</b></a> action. Be aware, instead of using the CAS procedure, I could execute the same action with Python, R, or even a REST API with some slight changes to the syntax for the specific language.</p>
<h2>Why not PROC SQL?</h2>
<p>The FedSQL language is the SAS implementation of the ANSI SQL:1999 core standard. FedSQL provides a scalable, threaded, high-performance way to query data and create tables.  FedSQL also enables you to process and join data using industry-standard query expressions and SQL expressions. In SAS Viya, the <strong>execDirect</strong> CAS action submits a SAS FedSQL language statement for immediate execution in the CAS server. Moreover, you can also use PROC FEDSQL to query tables in CAS. Behind the scenes the CAS API converts the procedure to the <strong>execDirect</strong> action.</p>
<p>For my PROC SQL fans, be careful. If you use PROC SQL to query a CAS table, the entire CAS table is sent back to the client for processing. This can cause slow performance or cause a data transfer error because <em><strong>PROC SQL does not execute in CAS.</strong></em></p>
<h2>Execute SQL in SAS Viya</h2>
<p>Consider the code below. To execute fedSQL directly in CAS, use the <strong>fedSQL.execDirect</strong> CAS action with the <strong>query</strong> parameter. In the <strong>query</strong> parameter specify the query as a string. In the FROM clause use a two level naming convention to specify the CAS table name and caslib. Here I'll specify the <b>cars </b>table in the <strong>Casuser</strong> caslib.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">proc cas</span>;
    fedSQL.execDirect / 
        query=<span style="color: #a020f0;">&quot;select Make,
                      Model,
                      MSRP,
                      mean(MPG_City,MPG_Highway) as MPG_Avg
               from casuser.cars
               where Make='Toyota'
               order by MPG_Avg desc&quot;</span>;
<span style="color: #000080; font-weight: bold;">quit</span>;</pre></td></tr></table></div>

<p>And the results:<br />
<a href="https://blogs.sas.com/content/sgf/2021/09/28/cas-action-executing-sql-in-sas-viya/execdirect-sql/" rel="attachment wp-att-32442"><img loading="lazy" class="alignnone size-full wp-image-32442" src="https://blogs.sas.com/content/sgf/files/2021/06/execDirect-SQL.png" alt="" width="410" height="214" srcset="https://blogs.sas.com/content/sgf/files/2021/06/execDirect-SQL.png 410w, https://blogs.sas.com/content/sgf/files/2021/06/execDirect-SQL-300x157.png 300w" sizes="(max-width: 410px) 100vw, 410px" /></a></p>
<p>The <strong>execDirect</strong> action executes the query in the distributed CAS environment and returns the expected results.</p>
<h2>Using a SOURCE block</h2>
<p>While the query we executed was simple, this is not always the case. Adding a complicated query as a string can make writing the query difficult.</p>
<p>Instead of specifying the query as a string in the CAS procedure, use the SOURCE statement to embed text in a variable. In the following example, I'll execute the same query as before. However, this time I'll nest the query inside a SOURCE block by specifying the SOURCE statement and name the variable <strong>MPG_toyota</strong>. Then I'll add the query inside the SOURCE block and use the <strong>ENDSOURCE</strong> statement to end the block.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">proc cas</span>;
    source MPG_toyota;
        <span style="color: #0000ff;">select</span> Make,
               Model,
               MSRP,
               <span style="color: #0000ff;">mean</span><span style="color: #66cc66;">&#40;</span>MPG_City,MPG_Highway<span style="color: #66cc66;">&#41;</span> <span style="color: #0000ff;">as</span> MPG_Avg
        <span style="color: #0000ff;">from</span> casuser.cars
        <span style="color: #0000ff;">where</span> Make=<span style="color: #a020f0;">'Toyota'</span>
        <span style="color: #0000ff;">order</span> <span style="color: #0000ff;">by</span> MPG_Avg desc;
    endsource;
&nbsp;
    fedSQL.execDirect / query=MPG_toyota;
<span style="color: #000080; font-weight: bold;">quit</span>;</pre></td></tr></table></div>

<p>After the SOURCE block is complete, you can reference the variable as the value to the <strong>query</strong> parameter in the <strong>execDirect</strong> action.</p>
<p>And the results:</p>
<p><a href="https://blogs.sas.com/content/sgf/2021/09/28/cas-action-executing-sql-in-sas-viya/execdirect-sql/" rel="attachment wp-att-32442"><img loading="lazy" class="alignnone size-full wp-image-32442" src="https://blogs.sas.com/content/sgf/files/2021/06/execDirect-SQL.png" alt="" width="410" height="214" srcset="https://blogs.sas.com/content/sgf/files/2021/06/execDirect-SQL.png 410w, https://blogs.sas.com/content/sgf/files/2021/06/execDirect-SQL-300x157.png 300w" sizes="(max-width: 410px) 100vw, 410px" /></a></p>
<p>The results returned are the same, but using a SOURCE block makes the code easier to write and maintain.</p>
<h2>Summary</h2>
<p>In SAS Viya, FedSQL provides a scalable, threaded, high-performance way to query data and create new CAS tables from existing tables in the CAS server. In this example we saw two distinct ways to run SQL code on SAS Viya. This is only the beginning. See the resources below for more details on PROC FedSQL.</p>
<h3>Resources</h3>
<p><a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/casfedsql/titlepage.htm">SAS® Viya®: FedSQL Programming for SAS® Cloud Analytic Services</a><br />
<a href="https://blogs.sas.com/content/sgf/2019/10/22/sas-viya-how-to-emulate-proc-sql-using-cas-enabled-proc-fedsql/">SAS® Viya®: How to Emulate PROC SQL Using CAS-Enabled PROC FedSQL</a><br />
<a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_017/proc/p0ahxz9t4dkcucn1uiqa42nbazbh.htm?homeOnFail">FEDSQL Procedure</a><br />
<a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_014/caspg/cas-fedsql-execdirect.htm" target="_blank" rel="noopener noreferrer">execDirect CAS Action</a><br />
<a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_014/proccas/p1nh54k4wc2sgyn1g66ietjwmwsn.htm" target="_blank" rel="noopener noreferrer">SOURCE statement</a><br />
<a href="https://go.documentation.sas.com/doc/en/pgmsascdc/v_012/grstatproc/p0tngvy99l0bgdn10xabchb6kqtr.htm?homeOnFail" target="_blank" rel="noopener noreferrer">SAS® Cloud Analytic Services: Fundamentals</a><br />
<a href="https://blogs.sas.com/content/sgf/files/2021/06/Execute-SQL-in-CAS.txt" target="_blank" rel="noopener noreferrer">Code</a></p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/09/28/cas-action-executing-sql-in-sas-viya/">CAS-Action! Executing SQL in SAS Viya</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=hrQP7OKAc-M:ciJ6pRqatJc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=hrQP7OKAc-M:ciJ6pRqatJc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=hrQP7OKAc-M:ciJ6pRqatJc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=hrQP7OKAc-M:ciJ6pRqatJc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=hrQP7OKAc-M:ciJ6pRqatJc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=hrQP7OKAc-M:ciJ6pRqatJc:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=hrQP7OKAc-M:ciJ6pRqatJc:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=hrQP7OKAc-M:ciJ6pRqatJc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=hrQP7OKAc-M:ciJ6pRqatJc:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/09/28/cas-action-executing-sql-in-sas-viya/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2021/06/Execute-SQL-in-CAS-150x150.jpg" />
	</item>
		<item>
		<title>Authentication to SAS Viya: a couple of approaches</title>
		<link>https://blogs.sas.com/content/sgf/2021/09/24/authentication-to-sas-viya/</link>
					<comments>https://blogs.sas.com/content/sgf/2021/09/24/authentication-to-sas-viya/#comments</comments>
		
		<dc:creator><![CDATA[Joe Furbee]]></dc:creator>
		<pubDate>Fri, 24 Sep 2021 16:33:13 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Developers]]></category>
		<category><![CDATA[REST APIs]]></category>
		<category><![CDATA[SAS REST APIs]]></category>
		<category><![CDATA[SAS Viya]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[tips & techniques]]></category>
		<guid isPermaLink="false">https://blogs.sas.com/content/sgf/?p=18791</guid>

					<description><![CDATA[<p>In my blog series regarding SAS REST APIs (you can read all of my posts on this topic here) I outlined how to integrate SAS analytical capabilities into applications. I detailed how to construct REST calls, build body parameters and interpret the responses. I've not yet covered authentication for the [...]</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/09/24/authentication-to-sas-viya/">Authentication to SAS Viya: a couple of approaches</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div id="attachment_18793" style="width: 361px" class="wp-caption alignright"><a href="https://blogs.sas.com/content/sgf/files/2019/01/cartBeforeHorse.png"><img aria-describedby="caption-attachment-18793" loading="lazy" src="https://blogs.sas.com/content/sgf/files/2019/01/cartBeforeHorse-351x185.png" alt="" width="351" height="185" class="size-main-block wp-image-18793" /></a><p id="caption-attachment-18793" class="wp-caption-text">Need to authenticate on REST API calls</p></div>
In my blog series regarding SAS REST APIs <a href="https://blogs.sas.com/content/tag/rest-apis/" rel="noopener noreferrer" target="_blank">(you can read all of my posts on this topic here)</a> I outlined how to integrate SAS analytical capabilities into applications. I detailed how to construct REST calls, build body parameters and  interpret the responses. I've not yet covered authentication for the operations, purposefully putting <a href="https://en.wikipedia.org/wiki/Cart_before_the_horse" rel="noopener noreferrer" target="_blank">the cart before the horse</a>. If you're not authenticated, you can't do much, so this post will help to get the horse and cart in the right order.</p>
<p>While researching authentication I ran into a couple of resources on SAS and OAuth. First,  what I consider the gold standard in Mike Roda’s SAS Global Forum paper <a href="https://www.sas.com/content/dam/SAS/support/en/sas-global-forum-proceedings/2018/1737-2018.pdf">OpenID Connect Opens the Door to SAS Viya APIs</a>. We have also re-written the <a href="https://developer.sas.com/apis/rest/Topics/">SAS Viya REST API ‘Getting Started’ documentation</a> on <a href="https://developer.sas.com/home.html">developer.sas.com</a>,  which covers details on application registration and access token generation. The rewrite includes sample code for both curl and Python.</p>
<p>Consider this post a quick guide to summarize these resources and shed light on authenticating via authorization code and passwords.</p>
<h1>What OAuth grant type should I use?</h1>
<p>Choosing the grant method to get an access token with OAuth depends entirely on your application. You can start with this guide <a href="https://oauth2.thephpleague.com/authorization-server/which-grant/">Which OAuth 2.0 grant should I implement?</a> to understand the basics of OAuth grant type options. For a SAS perspective, refer to Tara St. Clair’s article <a href="https://blogs.sas.com/content/sgf/2020/09/14/building-custom-apps-on-top-of-sas-viya-part-three-choosing-an-oauth-flow/">Building custom apps on top of SAS Viya, Part Three: Choosing an OAuth flow</a>. </p>
<p>This post covers three grant methods: authorization code, client credentials, and password. Authorization code grants are generally used with web applications and considered the safest choice. The client credentials grant is not associated with any user and is scoped according to the authorities registered to the client. Password grants are most often used by mobile apps and applied in trusted environments. The password grant type is not considered secure and should not be used in production environments.</p>
<h1>The process, briefly</h1>
<p>Getting an external application connected to the SAS Viya platform requires a series of steps. The process below pertain to the authorization code grant type; however, the steps are similar for all grant types.</p>
<ol>
<li>Use the SAS Viya configuration server's Consul token to obtain an Access Token to register a new Client ID</li>
<li>Use the Access Token to register the new client ID and secret</li>
<li>Obtain the authorization code</li>
<li>Acquire the OAuth access token of the Client ID using the authorization code</li>
<li>Call the SAS Viya API using the access token for the authentication.</li>
</ol>
<p>The process requires multiple roles. A SAS administrator performs steps 1 and 2. A script or app provides the URL to an end user for step 3. This produces an authorization code and the user plugs it back into the script or application, so it can continue.</p>
<p>Registering the client and getting the authorization code (steps 1,2, and 3) are one-time processes. The access and refresh tokens (step 4) are created once and only need to be refreshed if/when the token expires. Once you have the access token, you can call any API (step 5) if your access token is valid.</p>
<h1>The process, in detail</h1>
<p>Let's look at each grant type in more detail.</p>
<h2>Get an access token using an authorization code</h2>
<p>For all three grant types covered, you must register the client. The process explained here is in the context of the the authorization code grant type. The client registration process is the same across all grant types, except for the authorization_code parameter. It must match the grant type procedure followed by the user later on. </p>
<h3> Step 1: Get the SAS Viya Consul token to register a new client</h3>
<p>The first step to register the client is to get the consul token from the SAS server. As a SAS administrator (sudo user), access the consul token using the following commands:</p>
<h4>For SAS Viya 3.5 and before</h4>
<p>On the SAS Viya server, run the following command to get the Consul token and add it to the CONSUL_TOKEN environment variable:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">CONSUL_TOKEN</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>sas<span style="color: #000000; font-weight: bold;">/</span>viya<span style="color: #000000; font-weight: bold;">/</span>config<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>SASSecurityCertificateFramework<span style="color: #000000; font-weight: bold;">/</span>tokens<span style="color: #000000; font-weight: bold;">/</span>consul<span style="color: #000000; font-weight: bold;">/</span>default<span style="color: #000000; font-weight: bold;">/</span>client.token<span style="color: #000000; font-weight: bold;">`</span></pre></td></tr></table></div>

<p><strong>And the response:</strong> <code>64e01b03-7dab-41be-a104-2231f99d7dd8</code> (when not stored in a variable).</p>
<h4>For SAS Viya 2020.1 and later</h4>
<p>On the SAS Viya cluster, run the following command to get the Consul token (replace  value to fit your environment):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">kubectl <span style="color: #660033;">-n</span> <span style="color: #000000; font-weight: bold;">&lt;</span>namespace<span style="color: #000000; font-weight: bold;">&gt;</span> get secret sas-consul-client <span style="color: #660033;">-o</span> <span style="color: #007800;">jsonpath</span>=<span style="color: #ff0000;">&quot;{.data.CONSUL_TOKEN}&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(base64 -d)</span>&quot;</span></pre></td></tr></table></div>

<p><strong>And the response:</strong>  <code>64e01b03-7dab-41be-a104-2231f99d7dd8</code></p>
<p>The Consul token returns and is used to obtain an access token used to register the new application. Use the following cURL command to get the token:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ curl <span style="color: #660033;">-k</span> <span style="color: #660033;">-X</span> POST <span style="color: #ff0000;">&quot;https://sasserver.demo.sas.com/SASLogon/oauth/clients/consul?callback=false&amp;serviceId=myclientid&quot;</span> \
     <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;X-Consul-Token: <span style="color: #007800;">$CONSUL_TOKEN</span>&quot;</span></pre></td></tr></table></div>

<p><strong>And the response:</strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"> <span style="color: #009900;">&#123;</span>
   <span style="color: #3366CC;">&quot;access_token&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;eyJhbGciOiJSUzI1NiIsIm...&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;token_type&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;bearer&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;expires_in&quot;</span><span style="color: #339933;">:</span><span style="color: #CC0000;">35999</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;scope&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;uaa.admin&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;jti&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;de81c7f3cca645ac807f18dc0d186331&quot;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Where <em>serviceid </em>in the URL represents the name of the client to register ('myclientid' in this case). The returned token can be lengthy. To assist in later use, create an environment variable from the returned token:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666;">$ </span><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">IDTOKEN</span>=<span style="color: #ff0000;">&quot;eyJhbGciOiJSUzI1NiIsIm...&quot;</span></pre></td></tr></table></div>

<h3>Step 2: Register the new client</h3>
<p>Change the <em>client_id</em>, <em>client_secret</em>, and <em>scopes </em>in the code below. For detailed guidance on creating and managing Client IDs and Secrets, <a href="https://www.oauth.com/oauth2-servers/client-registration/client-id-secret/">refer to this page</a>. Scopes should always include "openid" along with any other groups this client needs to get in the access tokens. You can specify "*" but then the user gets prompted for all available groups. The example below just uses one additional group named "group1". Check with your SAS administrator for which scopes to include. You can find more information on scopes and authorities (related parameter for client credentials grant) in <a href="https://communities.sas.com/t5/Developers/Get-list-of-available-scopes-for-creating-a-client/m-p/658298#M831">this SAS Communities thread</a>.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ curl <span style="color: #660033;">-k</span> <span style="color: #660033;">-X</span> POST <span style="color: #ff0000;">&quot;https://sasserver.demo.sas.com/SASLogon/oauth/clients&quot;</span> \
     <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Content-Type: application/json&quot;</span> \
     <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Authorization: Bearer <span style="color: #007800;">$IDTOKEN</span>&quot;</span> \
     <span style="color: #660033;">-d</span> <span style="color: #ff0000;">'{
      &quot;client_id&quot;: &quot;myclientid&quot;, 
      &quot;client_secret&quot;: &quot;myclientsecret&quot;,
      &quot;scope&quot;: [&quot;openid&quot;, &quot;group1&quot;],
      &quot;authorized_grant_types&quot;: [&quot;authorization_code&quot;,&quot;refresh_token&quot;],
      &quot;redirect_uri&quot;: &quot;urn:ietf:wg:oauth:2.0:oob&quot;
     }'</span></pre></td></tr></table></div>

<p><strong>And the response:</strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
   <span style="color: #3366CC;">&quot;scope&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span>
      <span style="color: #3366CC;">&quot;openid&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;group1&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;client_id&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;myclientid&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;resource_ids&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span>
      <span style="color: #3366CC;">&quot;none&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;authorized_grant_types&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span>
      <span style="color: #3366CC;">&quot;refresh_token&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;authorization_code&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;redirect_uri&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span>
      <span style="color: #3366CC;">&quot;urn:ietf:wg:oauth:2.0:oob&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;autoapprove&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;authorities&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span>
      <span style="color: #3366CC;">&quot;uaa.none&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;lastModified&quot;</span><span style="color: #339933;">:</span><span style="color: #CC0000;">1547138692523</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;required_user_groups&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>Step 3: Approve access to get authentication code</h3>
<p>Place the following URL in a browser. Change the <em>hostname</em> and <em>myclientid</em> in the URL as needed.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">https:<span style="color: #000000; font-weight: bold;">//</span>sasserver.demo.sas.com<span style="color: #000000; font-weight: bold;">/</span>SASLogon<span style="color: #000000; font-weight: bold;">/</span>oauth<span style="color: #000000; font-weight: bold;">/</span>authorize?<span style="color: #007800;">client_id</span>=myclientid<span style="color: #000000; font-weight: bold;">&amp;</span><span style="color: #007800;">response_type</span>=code</pre></td></tr></table></div>

<p>The browser redirects to the SAS login screen. Log in with your SAS user credentials.<br />
<div id="attachment_18808" style="width: 712px" class="wp-caption aligncenter"><a href="https://blogs.sas.com/content/sgf/files/2019/01/sasLoginScreen.png"><img aria-describedby="caption-attachment-18808" loading="lazy" src="https://blogs.sas.com/content/sgf/files/2019/01/sasLoginScreen-1024x551.png" alt="" width="702" height="378" class="size-large wp-image-18808" srcset="https://blogs.sas.com/content/sgf/files/2019/01/sasLoginScreen-1024x551.png 1024w, https://blogs.sas.com/content/sgf/files/2019/01/sasLoginScreen-300x162.png 300w, https://blogs.sas.com/content/sgf/files/2019/01/sasLoginScreen.png 1917w" sizes="(max-width: 702px) 100vw, 702px" /></a><p id="caption-attachment-18808" class="wp-caption-text">SAS Login Screen</p></div>
<p>On the <em>Authorize Access</em> screen, select the <em>openid</em> checkbox (and any other required groups) and click the <em>Authorize Access</em> button.<br />
<div id="attachment_18806" style="width: 393px" class="wp-caption alignnone"><a href="https://blogs.sas.com/content/sgf/files/2019/01/authAccess.png"><img aria-describedby="caption-attachment-18806" loading="lazy" src="https://blogs.sas.com/content/sgf/files/2019/01/authAccess.png" alt="" width="383" height="389" class="size-full wp-image-18806" srcset="https://blogs.sas.com/content/sgf/files/2019/01/authAccess.png 383w, https://blogs.sas.com/content/sgf/files/2019/01/authAccess-295x300.png 295w" sizes="(max-width: 383px) 100vw, 383px" /></a><p id="caption-attachment-18806" class="wp-caption-text">Authorize Access form</p></div>
<p>After submitting the form, you'll see an authorization code. For example, "lB1sxkaCfg". You will use this code in the next step.<br />
<div id="attachment_18807" style="width: 390px" class="wp-caption alignnone"><a href="https://blogs.sas.com/content/sgf/files/2019/01/authCode.png"><img aria-describedby="caption-attachment-18807" loading="lazy" src="https://blogs.sas.com/content/sgf/files/2019/01/authCode.png" alt="" width="380" height="316" class="size-full wp-image-18807" srcset="https://blogs.sas.com/content/sgf/files/2019/01/authCode.png 380w, https://blogs.sas.com/content/sgf/files/2019/01/authCode-300x249.png 300w" sizes="(max-width: 380px) 100vw, 380px" /></a><p id="caption-attachment-18807" class="wp-caption-text">Authorization Code displays</p></div>
<h3>Step 4: Get an access token using the authorization code</h3>
<p>Now we have the authorization code and we'll use it in the following cURL command to get the access token to SAS.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ curl <span style="color: #660033;">-k</span> https:<span style="color: #000000; font-weight: bold;">//</span>sasserver.demo.sas.com<span style="color: #000000; font-weight: bold;">/</span>SASLogon<span style="color: #000000; font-weight: bold;">/</span>oauth<span style="color: #000000; font-weight: bold;">/</span>token \
     <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Accept: application/json&quot;</span> <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Content-Type: application/x-www-form-urlencoded&quot;</span> \
     <span style="color: #660033;">-u</span> <span style="color: #ff0000;">&quot;myclientid:myclientsecret&quot;</span> <span style="color: #660033;">-d</span> <span style="color: #ff0000;">&quot;grant_type=authorization_code&amp;code=YZuKQUg10Z&quot;</span></pre></td></tr></table></div>

<p><strong>And the response:</strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
   <span style="color: #3366CC;">&quot;access_token&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;eyJhbGciOiJSUzI1NiIsImtpZ...&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;token_type&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;bearer&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;refresh_token&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;eyJhbGciOiJSUzI1NiIsImtpZC...&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;expires_in&quot;</span><span style="color: #339933;">:</span><span style="color: #CC0000;">35999</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;scope&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;openid&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;jti&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;b35f26197fa849b6a1856eea1c722933&quot;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>We use the returned token to authenticate and authorize the calls made between the client and SAS. We also get a refresh token we use to issue a new token when the current one expires. This way we can avoid repeating all the previous steps. I explain the refresh process further down.</p>
<p>We will again create environment variables for the tokens.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">ACCESS_TOKEN</span>=<span style="color: #ff0000;">&quot;eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ...&quot;</span>
$ <span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">REFRESH_TOKEN</span>=<span style="color: #ff0000;">&quot;eyJhbGciOiJSUzI1NiIsImtpZC...&quot;</span></pre></td></tr></table></div>

<h3>Step 5: Use the access token to call SAS Viya APIs</h3>
<p>The prep work is complete. We can now send requests to SAS Viya and get some work done. Below is an example REST call that returns the top level folders.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ curl <span style="color: #660033;">-k</span> https:<span style="color: #000000; font-weight: bold;">//</span>sasserver.demo.sas.com<span style="color: #000000; font-weight: bold;">/</span>folders<span style="color: #000000; font-weight: bold;">/</span>folders?<span style="color: #007800;">filter</span>=isNull<span style="color: #7a0874; font-weight: bold;">&#40;</span>parent<span style="color: #7a0874; font-weight: bold;">&#41;</span> \
<span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Authorization: Bearer <span style="color: #007800;">$ACCESS_TOKEN</span>&quot;</span></pre></td></tr></table></div>

<p><strong>And the (partial) response:</strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;links&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;method&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;GET&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;rel&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;collection&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/folders/folders&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;uri&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/folders/folders&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/vnd.sas.collection&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;method&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;GET&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;rel&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;self&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/folders/folders?start=0&amp;limit=20&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;uri&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/folders/folders?start=0&amp;limit=20&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;application/vnd.sas.collection&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #3366CC;">&quot;method&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;POST&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;rel&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;createFolder&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;href&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/folders/folders&quot;</span><span style="color: #339933;">,</span>
...</pre></td></tr></table></div>

<h2>Use the refresh token to get a new access token</h2>
<p>To use the refresh token to get a new access token, simply send a cURL command like the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">$ curl <span style="color: #660033;">-k</span> https:<span style="color: #000000; font-weight: bold;">//</span>sasserver.demo.sas.com<span style="color: #000000; font-weight: bold;">/</span>SASLogon<span style="color: #000000; font-weight: bold;">/</span>oauth<span style="color: #000000; font-weight: bold;">/</span>token <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Accept: application/json&quot;</span> \
     <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Content-Type: application/x-www-form-urlencoded&quot;</span> \
     <span style="color: #660033;">-u</span> <span style="color: #ff0000;">&quot;myclientid:myclientsecret&quot;</span> \
     <span style="color: #660033;">-d</span> <span style="color: #ff0000;">&quot;grant_type=refresh_token&amp;refresh_token=<span style="color: #007800;">$REFRESH_TOKEN</span>&quot;</span></pre></td></tr></table></div>

<p><strong>And the response:</strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
   <span style="color: #3366CC;">&quot;access_token&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ...&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;token_type&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;bearer&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;refresh_token&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;eyJhbGciOiJSUzI1NiIsImtpZCSjYxrrNRCF7h0oLhd0Y&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;expires_in&quot;</span><span style="color: #339933;">:</span><span style="color: #CC0000;">35999</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;scope&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;openid&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;jti&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;a5c4456b5beb4493918c389cd5186f02&quot;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Note the access token is new, and the refresh token remains static. Use the new refresh token for future REST calls. Make sure to replace the ACCESS_TOKEN variable with the new token. Also, the access token has a default life of ten hours before it expires. Most applications deal with expiring and refreshing tokens programmatically. If you wish to change the default expiry of an access token in SAS, <a href="https://go.documentation.sas.com/?cdcId=calcdc&amp;cdcVersion=3.4&amp;docsetId=calconfig&amp;docsetTarget=n08025sasconfiguration0admin.htm&amp;locale=en#n08087sasconfiguration0admin" rel="noopener noreferrer" target="_blank">make a configuration change in the JWT properties</a> in SAS. </p>
<h2>Get an access token using the <strong>client credentials</strong> grant</h2>
<p>The steps to obtain an access token using the client credentials grant are similar to the authorization code. I highlight the differences below, without repeating all the steps. The process for registering the client is the same as described earlier, except for the grant type parameter where you will now use <code>&quot;authorized_grant_types&quot;: [&quot;client_credentials&quot;]</code>. With client credentials, there is no concept of a refresh token, so it's been removed from the parameter.</p>
<p>Now that the client is registered, the only thing left is to get the access token. Use the code below to get the token:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">curl <span style="color: #660033;">-k</span> <span style="color: #660033;">-X</span> POST <span style="color: #ff0000;">&quot;https://&lt;sas-server&gt;/SASLogon/oauth/token&quot;</span> \
       <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Content-Type: application/x-www-form-urlencoded&quot;</span> \
       <span style="color: #660033;">-d</span> <span style="color: #ff0000;">&quot;grant_type=client_credentials&quot;</span> \
       <span style="color: #660033;">-u</span> <span style="color: #ff0000;">&quot;myclientid:myclientsecret&quot;</span></pre></td></tr></table></div>

<p>That's it. You can now use the access token retuned in the preceeding call to make REST API calls.</p>
<h2>Get an access token using the <strong>password</strong> grant</h2>
<p>The steps to obtain an access token using the password grant are again similar to those describe earlier. When registering the client, use the password grant <code>&quot;authorized_grant_types&quot;: [&quot;password&quot;,&quot;refresh_token&quot;]</code>.</p>
<p>The client is now registered on the SAS Viya server. To get the access token, we send a command like we did when using the authorization code and client credentials, just using the username and password.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">curl <span style="color: #660033;">-k</span> https:<span style="color: #000000; font-weight: bold;">//</span>sasserver.demo.sas.com<span style="color: #000000; font-weight: bold;">/</span>SASLogon<span style="color: #000000; font-weight: bold;">/</span>oauth<span style="color: #000000; font-weight: bold;">/</span>token \
     <span style="color: #660033;">-H</span> <span style="color: #ff0000;">&quot;Content-Type: application/x-www-form-urlencoded&quot;</span> 
     <span style="color: #660033;">-u</span> <span style="color: #ff0000;">&quot;myclientid:myclientsecret&quot;</span> 
     <span style="color: #660033;">-d</span> <span style="color: #ff0000;">&quot;grant_type=password&amp;username=sasdemo&amp;password=mypassword&quot;</span></pre></td></tr></table></div>

<p><strong>And the response:</strong></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
   <span style="color: #3366CC;">&quot;access_token&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;eyJhbGciOiJSUzI1NiIsImtpZCI6Imx...&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;token_type&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;bearer&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;refresh_token&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;eyJhbGciOiJSUzI1NiIsImtpZ...&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;expires_in&quot;</span><span style="color: #339933;">:</span><span style="color: #CC0000;">43199</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;scope&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;DataBuilders ApplicationAdministrators SASScoreUsers clients.read clients.secret uaa.resource openid PlanningAdministrators uaa.admin clients.admin EsriUsers scim.read SASAdministrators PlanningUsers clients.write scim.write&quot;</span><span style="color: #339933;">,</span>
   <span style="color: #3366CC;">&quot;jti&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;073bdcbc6dc94384bcf9b47dc8b7e479&quot;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>From here, sending requests and refreshing the token steps are identical to the method explained in the other code examples.</p>
<h2> Final thoughts</h2>
<p>At first, OAuth seems a little intimidating; however, after registering the client and creating the access and refresh tokens, the application will handle all authentication components . This process runs smoothly if you plan and make decisions up front. I hope this guide clears up any question you may have on securing your application with SAS. Please leave questions or comments below.</p>
<p><a rel="nofollow" href="https://blogs.sas.com/content/sgf/2021/09/24/authentication-to-sas-viya/">Authentication to SAS Viya: a couple of approaches</a> was published on <a rel="nofollow" href="https://blogs.sas.com/content/sgf">SAS Users</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=70r_XAnsO4o:FlZ2fQ4TPYI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=70r_XAnsO4o:FlZ2fQ4TPYI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=70r_XAnsO4o:FlZ2fQ4TPYI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=70r_XAnsO4o:FlZ2fQ4TPYI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=70r_XAnsO4o:FlZ2fQ4TPYI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=70r_XAnsO4o:FlZ2fQ4TPYI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=70r_XAnsO4o:FlZ2fQ4TPYI:TzevzKxY174"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?d=TzevzKxY174" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?a=70r_XAnsO4o:FlZ2fQ4TPYI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/SasGlobalForumBlog?i=70r_XAnsO4o:FlZ2fQ4TPYI:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blogs.sas.com/content/sgf/2021/09/24/authentication-to-sas-viya/feed/</wfw:commentRss>
			<slash:comments>47</slash:comments>
		
		
			<enclosure url="https://blogs.sas.com/content/sgf/files/2019/01/cartBeforeHorse-150x150.png" />
	</item>
	</channel>
</rss>
