<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>philihp.com &#187; Metadata</title>
	<atom:link href="http://www.philihp.com/blog/tag/metadata/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.philihp.com/blog</link>
	<description>I do things, and then I tell the internet about them.</description>
	<lastBuildDate>Mon, 06 Feb 2012 05:40:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Abusing Hash objects as a Stack in SAS Data Step</title>
		<link>http://www.philihp.com/blog/2010/abusing-hash-objects-as-a-stack-in-sas-data-step/</link>
		<comments>http://www.philihp.com/blog/2010/abusing-hash-objects-as-a-stack-in-sas-data-step/#comments</comments>
		<pubDate>Fri, 07 May 2010 21:00:40 +0000</pubDate>
		<dc:creator>philihp</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[data step]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[Metadata]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[SAS]]></category>
		<category><![CDATA[stack]]></category>
		<category><![CDATA[traverse]]></category>

		<guid isPermaLink="false">http://www.philihp.com/blog/?p=566</guid>
		<description><![CDATA[Everyone in the computer science field (should) eventually learn or realize that any recursive function can be rewritten as an iterative process with the aid of a stack. Since a SAS Data Step is iterative, it&#8217;s fairly easy to look up children of a tree node in metadata, but nearly impossible to recursively look up [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone in the computer science field (<em>should</em>) eventually learn or realize that any recursive function can be rewritten as an iterative process with the aid of a stack. Since a SAS Data Step is iterative, it&#8217;s fairly easy to look up children of a tree node in metadata, but nearly impossible to recursively look up children of children, and so fourth, without breaking out of the Data Step loop and into macro code, because there&#8217;s no native program stack.</p>
<p>You can use the <a href="http://support.sas.com/documentation/cdl/en/lrdict/62618/HTML/default/a000201972.htm">LINK</a> keyword, but that just keeps the <a href="http://en.wikipedia.org/wiki/Program_counter">PC register</a> in a stack to return to where you were a subroutine was called, it doesn&#8217;t recreate the data vector. Because of this, all variables in a SAS Data Step behave as global within the data step block.</p>
<p>You could use a _TEMPORARY_ array as a stack, but its size has to be hard-coded to a predetermined depth.</p>
<p>SAS 9 has a rarely used Hash object, which can be used within a Data Step. It grows as needed, so it can be used to function as a functionally infinite length array, and further abused to function as a stack within a Data Step. The following code demonstrates this:</p>
<pre>data _null_;
  declare hash stack();
  length stackvar $100;
  length stackdepth 8.;
  stackdepth=0;
  rc=stack.defineKey('stackdepth');
  rc=stack.defineData('stackvar');
  rc=stack.defineDone();

  stackvar='a';
  stackdepth+1;
  rc=stack.add();
  put 'push' stackdepth= stackvar=; 

  stackvar='b';
  stackdepth+1;
  rc=stack.add();
  put 'push' stackdepth= stackvar=; 

  stackvar='c';
  stackdepth+1;
  rc=stack.add();
  put 'push' stackdepth= stackvar=; 

  rc=stack.find();
  rc=stack.remove();
  put 'pop' stackdepth= stackvar=;
  stackdepth+-1;

  rc=stack.find();
  rc=stack.remove();
  put 'pop' stackdepth= stackvar=;
  stackdepth+-1;

  rc=stack.find();
  rc=stack.remove();
  put 'pop' stackdepth= stackvar=;
  stackdepth+-1;

  stackvar='x';
  stackdepth+1;
  rc=stack.add();
  put 'push' stackdepth= stackvar=; 

  stackvar='y';
  stackdepth+1;
  rc=stack.add();
  put 'push' stackdepth= stackvar=; 

  stackvar='z';
  stackdepth+1;
  rc=stack.add();
  put 'push' stackdepth= stackvar=; 

  rc=stack.find();
  rc=stack.remove();
  put 'pop' stackdepth= stackvar=;
  stackdepth+-1;

  rc=stack.find();
  rc=stack.remove();
  put 'pop' stackdepth= stackvar=;
  stackdepth+-1;

  rc=stack.find();
  rc=stack.remove();
  put 'pop' stackdepth= stackvar=;
  stackdepth+-1;
run;</pre>
<p>It outputs this:</p>
<pre>pushstackdepth=1 stackvar=a
pushstackdepth=2 stackvar=b
pushstackdepth=3 stackvar=c
popstackdepth=3 stackvar=c
popstackdepth=2 stackvar=b
popstackdepth=1 stackvar=a
pushstackdepth=1 stackvar=x
pushstackdepth=2 stackvar=y
pushstackdepth=3 stackvar=z
popstackdepth=3 stackvar=z
popstackdepth=2 stackvar=y
popstackdepth=1 stackvar=x</pre>
<p>By doing this, you can traverse a tree in metadata.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.philihp.com/blog/2010/abusing-hash-objects-as-a-stack-in-sas-data-step/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looping through SAS metadata objects</title>
		<link>http://www.philihp.com/blog/2010/looping-through-sas-metadata-objects/</link>
		<comments>http://www.philihp.com/blog/2010/looping-through-sas-metadata-objects/#comments</comments>
		<pubDate>Wed, 05 May 2010 20:07:47 +0000</pubDate>
		<dc:creator>philihp</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[for]]></category>
		<category><![CDATA[loop]]></category>
		<category><![CDATA[Metadata]]></category>
		<category><![CDATA[SAS]]></category>

		<guid isPermaLink="false">http://www.philihp.com/blog/?p=550</guid>
		<description><![CDATA[The following is my attempt at SAS Golf, where in a Data Step, I try to list the associations of a metadata object to the log. This is basically just taking advantage of combining SAS for loops with SAS while loops. I thought it was cool. Usually I find myself doing this with metadata_getnasn, metadata_getnprp, [...]]]></description>
			<content:encoded><![CDATA[<p>The following is my attempt at SAS Golf, where in a Data Step, I try to list the associations of a metadata object to the log. This is basically just taking advantage of combining SAS for loops with SAS while loops. I thought it was cool. Usually I find myself doing this with <a href="http://support.sas.com/documentation/cdl/en/lrmeta/60739/HTML/default/getnasn.htm">metadata_getnasn</a>, <a href="http://support.sas.com/documentation/cdl/en/lrmeta/60739/HTML/default/getnprp.htm">metadata_getnprp</a>, and <a href="http://support.sas.com/documentation/cdl/en/lrmeta/60739/HTML/default/getnobj.htm">metadata_getnobj</a></p>
<ul>
<li>n &#8211; index for the nth association</li>
<li>u &#8211; uri to object</li>
<li>a &#8211; association</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #000080; font-weight: bold;">data</span>;
  ...
  <span style="color: #0000ff;">do</span> <span style="color: #0000ff;">n</span>=<span style="color: #2e8b57; font-weight: bold;">1</span> <span style="color: #0000ff;">by</span> <span style="color: #2e8b57; font-weight: bold;">1</span> <span style="color: #0000ff;">while</span><span style="color: #66cc66;">&#40;</span>n&lt;r <span style="color: #0000ff;">or</span> r&lt;=<span style="color: #2e8b57; font-weight: bold;">0</span><span style="color: #66cc66;">&#41;</span>;
    r=metadata_getnasl<span style="color: #66cc66;">&#40;</span>u,<span style="color: #0000ff;">n</span>,a<span style="color: #66cc66;">&#41;</span>;
    <span style="color: #0000ff;">put</span> a;
  <span style="color: #0000ff;">end</span>;
  ...
<span style="color: #000080; font-weight: bold;">run</span>;</pre></div></div>

<p><strong>UPDATE:</strong> The <a href="http://support.sas.com/kb/19/977.html">metadata_getnass</a> function has been renamed to <a href="http://support.sas.com/documentation/cdl/en/lrmeta/60739/HTML/default/getnasn.htm">metadata_getnasn</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.philihp.com/blog/2010/looping-through-sas-metadata-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>For loops in SAS</title>
		<link>http://www.philihp.com/blog/2009/for-loops-in-sas/</link>
		<comments>http://www.philihp.com/blog/2009/for-loops-in-sas/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 16:06:22 +0000</pubDate>
		<dc:creator>philihp</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[For loops]]></category>
		<category><![CDATA[List iteration]]></category>
		<category><![CDATA[Metadata]]></category>
		<category><![CDATA[SAS]]></category>

		<guid isPermaLink="false">http://www.philihp.com/blog/?p=490</guid>
		<description><![CDATA[When coding for loops in SAS, one neat thing to remember is that all of the parts of it are optional. start &#60;TO stop&#62; &#60;BY increment&#62; &#60;WHILE(expression) &#124; UNTIL(expression)&#62; http://support.sas.com/documentation/cdl/en/lrdict/62618/HTML/default/a000201276.htm So in another language, what might be for&#40;int i=0;i &#60; max;i++&#41; &#123; In SAS, you can leave out the &#8220;by 1&#8243;, since it&#8217;s the default [...]]]></description>
			<content:encoded><![CDATA[<p>When coding for loops in SAS, one neat thing to remember is that all of the parts of it are optional.</p>
<blockquote><p>start &lt;TO stop&gt; &lt;BY increment&gt; &lt;WHILE(expression) | UNTIL(expression)&gt;</p>
<p><a href="http://support.sas.com/documentation/cdl/en/lrdict/62618/HTML/default/a000201276.htm"><cite>http://support.sas.com/documentation/cdl/en/lrdict/62618/HTML/default/a000201276.htm</cite></a></p></blockquote>
<p>So in another language, what might be</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>i <span style="color: #339933;">&lt;</span> max<span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></pre></div></div>

<p>In SAS, you can leave out the &#8220;by 1&#8243;, since it&#8217;s the default increment. So this would be</p>

<div class="wp_syntax"><div class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #0000ff;">do</span> i=<span style="color: #2e8b57; font-weight: bold;">0</span> to <span style="color: #0000ff;">max</span>;</pre></div></div>

<p>What&#8217;s fun is in SAS you can combine a <a href="http://en.wikipedia.org/wiki/Do_while_loop">Repeat-Until/Do-While</a> loop with a for loop. This might be useful if for some reason you don&#8217;t set the var &#8220;max&#8221; until you&#8217;ve iterated through the loop once, such as in this case, where &#8220;<a href="http://support.sas.com/documentation/cdl/en/lrmeta/60739/HTML/default/getnobj.htm">metadata_getnobj</a>&#8221; returns a negative on fail, but otherwise returns the number of objects that match the query.</p>

<div class="wp_syntax"><div class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #0000ff;">do</span> i=<span style="color: #2e8b57; font-weight: bold;">1</span> <span style="color: #0000ff;">by</span> <span style="color: #2e8b57; font-weight: bold;">1</span> <span style="color: #0000ff;">until</span> <span style="color: #66cc66;">&#40;</span>i &gt;= objs<span style="color: #66cc66;">&#41;</span>;
  rc=metadata_getnobj<span style="color: #66cc66;">&#40;</span><span style="color: #a020f0;">&quot;omsobj:SASLibrary?@Libref='MYLIBREF'&quot;</span>,i,uri<span style="color: #66cc66;">&#41;</span>;
  <span style="color: #0000ff;">if</span> rc&gt;=<span style="color: #2e8b57; font-weight: bold;">0</span> <span style="color: #0000ff;">then</span> objs=rc;
&nbsp;
  rc=metadata_getnasn<span style="color: #66cc66;">&#40;</span>uri,<span style="color: #a020f0;">&quot;LibraryConnection&quot;</span>,<span style="color: #2e8b57; font-weight: bold;">1</span>,uri<span style="color: #66cc66;">&#41;</span>;
  <span style="color: #0000ff;">if</span> rc&gt;=<span style="color: #2e8b57; font-weight: bold;">0</span> <span style="color: #0000ff;">then</span> <span style="color: #0000ff;">leave</span>;
<span style="color: #0000ff;">end</span>;</pre></div></div>

<p>This code loops through all the libraries in the metadata with libref=&#8217;MYLIBREF&#8217;, and exits with a URI for the first one it sees with at least one LibraryConnection association. This is useful when you have a remote library pointing to a local library and they both have the same name and you want a URI to the remote one.</p>
<p>Another cool thing with FOR loops in SAS is iteration through lists. In Java, say you have a block like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> x <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">&quot;a&quot;</span>,<span style="color: #0000ff;">&quot;b&quot;</span>,<span style="color: #0000ff;">&quot;c&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;x=&quot;</span><span style="color: #339933;">+</span>x<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In SAS, this is simply</p>

<div class="wp_syntax"><div class="code"><pre class="sas" style="font-family:monospace;"><span style="color: #0000ff;">do</span> <span style="color: #0000ff;">x</span>=<span style="color: #a020f0;">&quot;a&quot;</span>,<span style="color: #a020f0;">&quot;b&quot;</span>,<span style="color: #a020f0;">&quot;c&quot;</span>;
  <span style="color: #0000ff;">put</span> <span style="color: #0000ff;">x</span>=;
<span style="color: #0000ff;">end</span>;</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.philihp.com/blog/2009/for-loops-in-sas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

