<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Using a List in a Macro Variable in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665538#M199019</link>
    <description>&lt;P&gt;So you need to repeat these statements&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;retain _ask;
if ask ="."
then ask = _ask;
else _ask = ask;
drop _ask;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;for a series of variables.&lt;/P&gt;
&lt;P&gt;Step 1: replace explicit varnames with macro variable, and set the macrovar&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let var=ask;
retain _&amp;amp;var.;
if &amp;amp;var. ="."
then &amp;amp;var. = _&amp;amp;var.;
else _&amp;amp;var. = &amp;amp;var.;
drop _&amp;amp;var.;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;To iterate through your variable list, do&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%do i = 1 %to %sysfunc(countw(&amp;amp;varnames.));
&amp;nbsp; %let var = %scan(&amp;amp;varnames.,&amp;amp;i.);
&amp;nbsp; /* your code to repeat */
%end;&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Sat, 27 Jun 2020 14:12:37 GMT</pubDate>
    <dc:creator>Kurt_Bremser</dc:creator>
    <dc:date>2020-06-27T14:12:37Z</dc:date>
    <item>
      <title>Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665531#M199012</link>
      <description>&lt;P&gt;Hey people,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm new to SAS and I'm sorry if this problem has a very simple solution that I'm to blind to see.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I want to define a Macro variable called "write_forward(varnames= , typelist=)" and the goal is to enter variables and the type of the variables to replace missing values of the variables with their last observation. Therefore I wrote:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;%macro write_forward (varnames, typelist);&lt;/P&gt;&lt;P&gt;data forward;&lt;BR /&gt;merge sorted_spread (in=a)&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sorted_transaction (in=b);&lt;BR /&gt;by time;&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retain _&amp;amp;varnames.;&lt;BR /&gt;if &amp;amp;varnames. = &amp;amp;typelist.&lt;BR /&gt;then &amp;amp;varnames. = _&amp;amp;varnames.;&lt;BR /&gt;else _&amp;amp;varnames. = &amp;amp;varnames.;&lt;BR /&gt;drop _&amp;amp;varnames.;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;%mend;&lt;/P&gt;&lt;P&gt;%write_forward (varnames= ask&lt;BR /&gt;,typelist= .);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And it works fine if I only enter one variable. The problem is that as soon as I enter more than one variable in the form of:&lt;/P&gt;&lt;P&gt;%write_forward(varnames= ask bid&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ,typelist= . .)&lt;/P&gt;&lt;P&gt;SAS takes this as a line and enters "ask bid" as varnames instead of entering "ask" and then do it again for the next element of the line "bid".&lt;/P&gt;&lt;P&gt;I searched quite a while for a solution but found nothing that explains my exact problem. I hope you can help me and if there are any necessary informations missing please just tell me and I will post them.&lt;/P&gt;</description>
      <pubDate>Sat, 27 Jun 2020 13:06:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665531#M199012</guid>
      <dc:creator>MonsterGnom</dc:creator>
      <dc:date>2020-06-27T13:06:08Z</dc:date>
    </item>
    <item>
      <title>Re: Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665533#M199014</link>
      <description>&lt;P&gt;Here's the problem. When you write a macro, and then run it, it must produce valid legal working SAS code. Your macro does not do this.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;if &amp;amp;varnames. = &amp;amp;typelist.&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;becomes&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;if ask bid = . .&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;when you run the macro, which is not legal valid working SAS code.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You probably want a loop of some sort, but honestly, your logic in the macro doesn't make any sense to me. Specifically this part:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;then &amp;amp;varnames. = _&amp;amp;varnames.;
else _&amp;amp;varnames. = &amp;amp;varnames.;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;So, I couldn't even help you write a macro with a loop at this time. Please write some code without macros and without macro variables that works and does what you want it to do (you need to test it to make sure it works and does what you want, do not skip this step) so we can see what you are really trying to do.&lt;/P&gt;</description>
      <pubDate>Sat, 27 Jun 2020 13:32:27 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665533#M199014</guid>
      <dc:creator>PaigeMiller</dc:creator>
      <dc:date>2020-06-27T13:32:27Z</dc:date>
    </item>
    <item>
      <title>Re: Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665534#M199015</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/328522"&gt;@MonsterGnom&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Could you please try the following method to impute missing value using LOCF method?&lt;/P&gt;
&lt;P&gt;No need to use a macroprogram.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
	merge sorted_spread (in=a) sorted_transaction (in=b);
	by time;
	id=1; /*identifier to group all observations together*/
run;

data forward (drop=id);
   update have(obs=0) have;
   by id;
   output;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 27 Jun 2020 13:34:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665534#M199015</guid>
      <dc:creator>ed_sas_member</dc:creator>
      <dc:date>2020-06-27T13:34:37Z</dc:date>
    </item>
    <item>
      <title>Re: Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665536#M199017</link>
      <description>First of all thanks for the answer. I think I see your point but my problem is that there are guidelines in the assignment I have to do. Earlier in the code we have to do the same task of writing missing values forward using a retain statement what lead me to&lt;BR /&gt;&lt;BR /&gt;retain _ask;&lt;BR /&gt;if ask ="."&lt;BR /&gt;then ask = _ask;&lt;BR /&gt;else _ask = ask;&lt;BR /&gt;drop _ask;&lt;BR /&gt;&lt;BR /&gt;and it does what it is supposed to do. Problem is another task wants me to do the same using this macro variable. The text of the task:&lt;BR /&gt;&lt;BR /&gt;"12. Again, merge the sorted datasets sorted_spread and sorted_transaction in a data step. However, now associate the transaction price with the bid-ask-spread at the beginning of the subsequent second after the trade. To do so, use the macro write_forward to write all the variables from the transaction dataset forward. Inparticular, the macro write_forward replaces the missing values of the variables. The list typelist specifies whether missing values are encoded with a dot.(numeric variables) or an emptystring""(character variables).&lt;BR /&gt;/* Example for a call of the macro*/&lt;BR /&gt;%write_forward(varnames=char_var1 num_var1 char_var2&lt;BR /&gt;,typelist="" . "");&lt;BR /&gt;After that, remove all the observations that still contain missing values in any of the variables price, ask, or bid. Perform all of these steps in a single data step. Call the resulting dataset forward."&lt;BR /&gt;&lt;BR /&gt;I thought the easiest way to do it would be using what I did before and just put it in a macro variable. And about the retain statement I thought I just use a new variable called _ask that remembers the last missing value and if the value in the original variable is missing it is replaced by the new _ask variable. If its not missing the _ask variable takes on the new value that is now the last non-missing one. At the end the new variable _ask is dropped because its pretty much only a helping hand. I hope this at least explains what I was doing.</description>
      <pubDate>Sat, 27 Jun 2020 13:52:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665536#M199017</guid>
      <dc:creator>MonsterGnom</dc:creator>
      <dc:date>2020-06-27T13:52:44Z</dc:date>
    </item>
    <item>
      <title>Re: Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665537#M199018</link>
      <description>Thanks for your answer. I would very much like to do it without a macro that is not necessary but as i wrote in my reply above I'm forced to do so as well as I'm forced to use a retain statement to write it forward in the beginning.</description>
      <pubDate>Sat, 27 Jun 2020 13:56:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665537#M199018</guid>
      <dc:creator>MonsterGnom</dc:creator>
      <dc:date>2020-06-27T13:56:06Z</dc:date>
    </item>
    <item>
      <title>Re: Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665538#M199019</link>
      <description>&lt;P&gt;So you need to repeat these statements&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;retain _ask;
if ask ="."
then ask = _ask;
else _ask = ask;
drop _ask;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;for a series of variables.&lt;/P&gt;
&lt;P&gt;Step 1: replace explicit varnames with macro variable, and set the macrovar&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let var=ask;
retain _&amp;amp;var.;
if &amp;amp;var. ="."
then &amp;amp;var. = _&amp;amp;var.;
else _&amp;amp;var. = &amp;amp;var.;
drop _&amp;amp;var.;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;To iterate through your variable list, do&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%do i = 1 %to %sysfunc(countw(&amp;amp;varnames.));
&amp;nbsp; %let var = %scan(&amp;amp;varnames.,&amp;amp;i.);
&amp;nbsp; /* your code to repeat */
%end;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 27 Jun 2020 14:12:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665538#M199019</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2020-06-27T14:12:37Z</dc:date>
    </item>
    <item>
      <title>Re: Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665539#M199020</link>
      <description>&lt;P&gt;While &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/11562"&gt;@Kurt_Bremser&lt;/a&gt; is pretty close, the macro won't work on a mix of character and numeric variables without additional complications. If you have a character variable, then &lt;FONT face="courier new,courier"&gt;&amp;amp;var='.'&lt;/FONT&gt; will work, but it won't work for numeric variables. So, are you really in the situation where one variable in &amp;amp;varnames could be character and another variable in &amp;amp;varnames could be numeric?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 27 Jun 2020 14:20:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665539#M199020</guid>
      <dc:creator>PaigeMiller</dc:creator>
      <dc:date>2020-06-27T14:20:14Z</dc:date>
    </item>
    <item>
      <title>Re: Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665542#M199021</link>
      <description>&lt;P&gt;There is an issue with the code sample you provided for a single variable.&amp;nbsp; &amp;nbsp;If the variable is numeric then the test condition is wrong because it is comparing a numeric value to a character value.&amp;nbsp; If the variable is character then you will make the new retained variable as numeric instead of as character.&amp;nbsp; That is because the first place it is used (first place where SAS needs to make a decision on the type, the RETAIN doesn' t need to know the type) is on the right side of an assignment statement, so SAS will assume the new variable is numeric.&amp;nbsp; This is probably why the macro is designed to take in TWO lists, one with the names and one with the types.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You can fix that by changing the code just a little bit. (Code formatting note: do not split a single statement into two lines without at least adding some indentation).&amp;nbsp; By using the MISSING() function you eliminate the need to know the type in advance.&amp;nbsp; By reversing the test condition you can have the new variable first appear on the LEFT side of the assignment statement so that SAS will create it to match the type of the value on the right side of the assignment statement.&amp;nbsp; Note that since the RETAIN statement, like the DROP statement, is not executable there is no need to have it first.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;if not missing(ask) then _ask = ask;
else ask=_ask;
retain _ask;
drop _ask;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;So now your macro does not even need the TYPELIST parameter.&amp;nbsp; And there is no need to include the rest of the data step in the macro, just the lines of data step code that you want to generate.&amp;nbsp; Just make sure to call the macro inside a data step so that the code is generated in a place where it makes sense.&amp;nbsp; You might want to write a note to the log if anyone tries to use the TYPELIST parameter.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro write_forward (varnames, typelist);
%local i var ;
%if %length(&amp;amp;typelist) %then %put NOTE: Ignoring TYPELIST input as it is not needed. &amp;amp;=typelist;
%do i=1 %to %sysfunc(countw(&amp;amp;varnames,%str( )));
  %let var=%scan(&amp;amp;varnames,%str( ));
if not missing(&amp;amp;var ) then _&amp;amp;var= &amp;amp;var;
else &amp;amp;var=_&amp;amp;var;
retain _&amp;amp;var;
drop _&amp;amp;var;
%end;
%mend write_forward;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;And you could use it like this to deal with 4 variables.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data forward;
  merge sorted_spread (in=a)
        sorted_transaction (in=b)
  ;
  by time;
  %write_forward (varnames= ask a b c)
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 27 Jun 2020 16:05:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665542#M199021</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2020-06-27T16:05:43Z</dc:date>
    </item>
    <item>
      <title>Re: Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665543#M199022</link>
      <description>&lt;P&gt;Sounds like this is homework then.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/11562"&gt;@Kurt_Bremser&lt;/a&gt;s given you all the tools you need to solve this in his most recent answer.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You can also reference the macro library appendix for sample code on creating loops to loop through a list if you want or you can look into call execute to run your macro multiple times for different variables.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I prefer the second approach as I find it much easier to debug.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;UCLA introductory tutorial on macro variables and macros&lt;BR /&gt;&lt;A href="https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/" target="_blank"&gt;https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;Tutorial on converting a working program to a macro&lt;BR /&gt;This method is pretty robust and helps prevent errors and makes it much easier to debug your code. Obviously biased, because I wrote it &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt; &lt;A href="https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md" target="_blank"&gt;https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;Examples of common macro usage - macro appendix&lt;BR /&gt;&lt;A href="https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Appendix/ta-p/291716" target="_blank"&gt;https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Appendix/ta-p/291716&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/328522"&gt;@MonsterGnom&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;Thanks for your answer. I would very much like to do it without a macro that is not necessary but as i wrote in my reply above I'm forced to do so as well as I'm forced to use a retain statement to write it forward in the beginning.&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 27 Jun 2020 16:21:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665543#M199022</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2020-06-27T16:21:37Z</dc:date>
    </item>
    <item>
      <title>Re: Using a List in a Macro Variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665549#M199024</link>
      <description>&lt;P&gt;Thanks a lot for your answer. First it didnt work cause I put the do statement before the data step but found the solution. So you're my todays hero KurtBremser.&lt;/P&gt;</description>
      <pubDate>Sat, 27 Jun 2020 17:44:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Using-a-List-in-a-Macro-Variable/m-p/665549#M199024</guid>
      <dc:creator>MonsterGnom</dc:creator>
      <dc:date>2020-06-27T17:44:25Z</dc:date>
    </item>
  </channel>
</rss>

