<?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: How to write a macro that loops over a list of strings and codes a new variable in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/753043#M237280</link>
    <description>&lt;P&gt;You have these two statements backwards:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;INPUT CheckCode $;
length CheckCode $20;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;By referencing CHECKCODE in the INPUT statement before you have defined it SAS will have to use the default length of $8 for the variable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Also these lines should NOT be indented. It will just confuse you and make it harder for you to notice how long the values actual are to intend those lines.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;datalines;
68462030868
70710120407
69238131906
31722065832
43598043060
; &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The extra RUN: statement between the end of the data step and the start of the PROC SQL is also not useful, but it does not really do much harm other than it might confuse some programmers into thinking they can include statements for the data step in between the end of the in-line data and that superfluous RUN statement.&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Thu, 08 Jul 2021 22:47:53 GMT</pubDate>
    <dc:creator>Tom</dc:creator>
    <dc:date>2021-07-08T22:47:53Z</dc:date>
    <item>
      <title>How to write a macro that loops over a list of strings and codes a new variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/751571#M236602</link>
      <description>&lt;P&gt;Hi, I'd appreciate your help regarding following:&lt;/P&gt;&lt;P&gt;My data&lt;/P&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;Personid&lt;/TD&gt;&lt;TD&gt;CharCode&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1111&lt;/TD&gt;&lt;TD&gt;88888886666&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;2222&lt;/TD&gt;&lt;TD&gt;92000000001&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;333&lt;/TD&gt;&lt;TD&gt;92000000002&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Mylist: ('8888888', '92000000001')&amp;nbsp; -&amp;gt; this is a very long list in actual dataset consisting of character variable&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;If Charcode (character variable) in my data contains anything in Mylist (even partially, not exact match), then I want to code a new variable Myfind, where Myfind=1. If Charcode does not match anything in mylist, then Myfind will be 0.&amp;nbsp;&lt;/P&gt;&lt;P&gt;Desired Output&lt;/P&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;Personid&lt;/TD&gt;&lt;TD&gt;CharCode&lt;/TD&gt;&lt;TD&gt;Myfind&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;1111&lt;/TD&gt;&lt;TD&gt;88888886666&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;2222&lt;/TD&gt;&lt;TD&gt;92000000001&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;333&lt;/TD&gt;&lt;TD&gt;92000000002&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;What I've tried:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data mydata;
ATTRIB Myfind Length=3 Label='Yes/no indicator';
set pharmdat2;
If index ((CharCode), '8888888')&amp;gt;0 Or If index ((CharCode), '92000000001')&amp;gt;0&amp;nbsp;
THEN Myfind=1;
ELSE Myfind=0;
run;

&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;This works, but very tedious. The fourth line is where I need to loop through without me going in and specifying every item in Mylist. Is there a way to modify just this part?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I've also tried:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%Let Mylist= ('8888888', '92000000001')

data mydata;
ATTRIB Myfind Length=3 Label='Yes/no indicator';
set pharmdat2;
If CharCode in: &amp;amp;Mylist
THEN Myfind=1;
ELSE Myfind=0;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;But this code returns Myfind=0 for all rows, although there is a Charcode to Mylist match that I know exists in this dataset dataset.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I also couldn't use like statement combined with '%Mylistitem%' because this is not a where statement.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 01 Jul 2021 21:18:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/751571#M236602</guid>
      <dc:creator>shyunk</dc:creator>
      <dc:date>2021-07-01T21:18:01Z</dc:date>
    </item>
    <item>
      <title>Re: How to write a macro that loops over a list of strings and codes a new variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/751805#M236718</link>
      <description>&lt;P&gt;hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/345964"&gt;@shyunk&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This could be bone using several techniques besides the tedious writing of all check values.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Using a loop as you suggest is complicated. All check values should be read into the data step as a text array and the the actual values in each observation should be matched against all array values.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Using a hash object would probably possible also, but it never got into my personal toolbox, so I will leave that to one of the hash gurus in this forum.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;My preferred solution in cases like this is a SQL join. A SAS ifn-function is used to provide the value of MyFind based on a match or not. In this example the match is made on the shortest string from start, but the EQT operator could be switched to a CONTAINS to cover partial matched within the string as well.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data mydata;
	PersonID = 1111; CharCode = '88888886666'; output;
	PersonID = 1122; CharCode = '88888886789'; output;
	PersonID = 1133; CharCode = '88888856780'; output;
	PersonID = 2222; CharCode = '92000000001'; output;
	PersonID = 333;  CharCode = '92000000002'; output;
run;

data mylist;
	length CheckCode $20;
	CheckCode = '8888888'; output;
	CheckCode = '92000000001'; output;
run;

proc sql;
	create table want as
		select distinct
			a.PersonID,
			a.CharCode,
			ifn(b.CheckCode ne '',1,0) as MyFind
		from mydata as a
		left join mylist as b
		on a.CharCode eqt b.CheckCode;
quit;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Result:&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="2021-07-02 20_52_14-Window.gif" style="width: 330px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/60913iE6334494593D82B9/image-size/large?v=v2&amp;amp;px=999" role="button" title="2021-07-02 20_52_14-Window.gif" alt="2021-07-02 20_52_14-Window.gif" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 02 Jul 2021 18:53:52 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/751805#M236718</guid>
      <dc:creator>ErikLund_Jensen</dc:creator>
      <dc:date>2021-07-02T18:53:52Z</dc:date>
    </item>
    <item>
      <title>Re: How to write a macro that loops over a list of strings and codes a new variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/751830#M236734</link>
      <description>&lt;P&gt;That worked great, Thank you!&lt;/P&gt;</description>
      <pubDate>Fri, 02 Jul 2021 22:29:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/751830#M236734</guid>
      <dc:creator>shyunk</dc:creator>
      <dc:date>2021-07-02T22:29:12Z</dc:date>
    </item>
    <item>
      <title>Re: How to write a macro that loops over a list of strings and codes a new variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/752966#M237237</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/12887"&gt;@ErikLund_Jensen&lt;/a&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you again for your help. I realized the code isn't doing exactly what I intended, when I ran into this issue. Do you have any thoughts on why this may be happening?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="sas"&gt;data mydata;
	PersonID = 11; CharCode = '68000000000'; output;
	PersonID = 22; CharCode = '70710120901'; output;
	PersonID = 33; CharCode = '69238131906'; output;
	PersonID = 44; CharCode = '31722065832'; output;
	PersonID = 55;  CharCode = '43598043060'; output;
run;


data mylist;
INPUT CheckCode $;
	length CheckCode $20;
	Datalines;
        68462030868
        70710120407
        69238131906
        31722065832
        43598043060
;; 
run;

proc sql;
	create table want as
		select distinct
			a.PersonID,
			a.CharCode,
			ifn(b.CheckCode ne '',1,0) as MyFind
		from mydata as a
		left join mylist as b
		on a.CharCode contains b.CheckCode;
quit;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This returns below, where CharCode is trimmed to 8 letters, and it cuts out the last three digits of everything. Therefore, although PersonID 22, 33 in mydata is not a match because of its last three digits, it has 1 for Myfind. I checked the length of Charcode, and it's set to 30 now. This is the same for my real (longer) dataset and my mock dataset. I would appreciate some guidance why SAS (or SQL) is automatically trimming it to 8 letters here. I want to have full 11 letters.&lt;/P&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;PersonID&lt;/TD&gt;&lt;TD&gt;CharCode&lt;/TD&gt;&lt;TD&gt;Myfind&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;11&lt;/TD&gt;&lt;TD&gt;68000000&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;22&lt;/TD&gt;&lt;TD&gt;70710120&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;33&lt;/TD&gt;&lt;TD&gt;69238131&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;44&lt;/TD&gt;&lt;TD&gt;31722065&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;55&lt;/TD&gt;&lt;TD&gt;43598043&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;Output Table 1&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;When I use eqt or = instead of contains, using my real dataset, the output is 0 for all myfind where it is unable to find any match (Output table2). Interestingly, when I use my mock dataset I get the same 8 letter truncated table as Output table 1&lt;/P&gt;&lt;PRE&gt; on a.CharCode eqt b.CheckCode;&lt;BR /&gt; on a.CharCode = b.CheckCode;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;PersonID&lt;/TD&gt;&lt;TD&gt;CharCode&lt;/TD&gt;&lt;TD&gt;Myfind&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;11&lt;/TD&gt;&lt;TD&gt;68000000&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;22&lt;/TD&gt;&lt;TD&gt;70710120&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;33&lt;/TD&gt;&lt;TD&gt;69238131&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;44&lt;/TD&gt;&lt;TD&gt;31722065&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;55&lt;/TD&gt;&lt;TD&gt;43598043&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;Output Table 2&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Your help is much appreciated!&lt;/P&gt;</description>
      <pubDate>Thu, 08 Jul 2021 18:32:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/752966#M237237</guid>
      <dc:creator>shyunk</dc:creator>
      <dc:date>2021-07-08T18:32:02Z</dc:date>
    </item>
    <item>
      <title>Re: How to write a macro that loops over a list of strings and codes a new variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/752982#M237247</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/345964"&gt;@shyunk&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I made two small changes. The first is to get the full check value by using a $20 informat. The other reverses the comparison so checkcode contains charcodee instead of the reverse. I Hope that helps.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data mydata;
	PersonID = 11; CharCode = '68000000000'; output;
	PersonID = 22; CharCode = '70710120901'; output;
	PersonID = 33; CharCode = '69238131906'; output;
	PersonID = 44; CharCode = '31722065832'; output;
	PersonID = 55;  CharCode = '43598043060'; output;
run;


data mylist;
	INPUT CheckCode $20.;
	/*length CheckCode $20;*/
	Datalines;
        68462030868
        70710120407
        69238131906
        31722065832
        43598043060
;; 
run;

proc sql;
	create table want as
		select distinct
			a.PersonID,
			a.CharCode,
			ifn(b.CheckCode ne '',1,0) as MyFind
		from mydata as a
		left join mylist as b
		/*on a.CharCode contains b.CheckCode;*/
		on b.CheckCode contains a.CharCode;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="charcode.gif" style="width: 316px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/61079i69EC395B73AD4280/image-size/large?v=v2&amp;amp;px=999" role="button" title="charcode.gif" alt="charcode.gif" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 08 Jul 2021 19:24:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/752982#M237247</guid>
      <dc:creator>ErikLund_Jensen</dc:creator>
      <dc:date>2021-07-08T19:24:18Z</dc:date>
    </item>
    <item>
      <title>Re: How to write a macro that loops over a list of strings and codes a new variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/753023#M237275</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/12887"&gt;@ErikLund_Jensen&lt;/a&gt;&amp;nbsp;Thank you, I realized I was setting the informat incorrectly for mydata (it was too long), which was why SAS was trying to truncate it. Now it's doing what I intended it to do. I learned a lot from your answers and cannot thank you enough!&lt;/P&gt;</description>
      <pubDate>Thu, 08 Jul 2021 22:05:31 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/753023#M237275</guid>
      <dc:creator>shyunk</dc:creator>
      <dc:date>2021-07-08T22:05:31Z</dc:date>
    </item>
    <item>
      <title>Re: How to write a macro that loops over a list of strings and codes a new variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/753043#M237280</link>
      <description>&lt;P&gt;You have these two statements backwards:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;INPUT CheckCode $;
length CheckCode $20;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;By referencing CHECKCODE in the INPUT statement before you have defined it SAS will have to use the default length of $8 for the variable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Also these lines should NOT be indented. It will just confuse you and make it harder for you to notice how long the values actual are to intend those lines.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;datalines;
68462030868
70710120407
69238131906
31722065832
43598043060
; &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The extra RUN: statement between the end of the data step and the start of the PROC SQL is also not useful, but it does not really do much harm other than it might confuse some programmers into thinking they can include statements for the data step in between the end of the in-line data and that superfluous RUN statement.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 08 Jul 2021 22:47:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/753043#M237280</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2021-07-08T22:47:53Z</dc:date>
    </item>
    <item>
      <title>Re: How to write a macro that loops over a list of strings and codes a new variable</title>
      <link>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/753270#M237384</link>
      <description>Thank you! Those are great suggestions.</description>
      <pubDate>Fri, 09 Jul 2021 19:14:28 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/How-to-write-a-macro-that-loops-over-a-list-of-strings-and-codes/m-p/753270#M237384</guid>
      <dc:creator>shyunk</dc:creator>
      <dc:date>2021-07-09T19:14:28Z</dc:date>
    </item>
  </channel>
</rss>

