<?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: Looping trough tabel and detect change value in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/614744#M179778</link>
    <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/305287"&gt;@Retep1972&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Welcome in this universe of nerds! It is good practice here to give some additional information, like code to create example input that can be copied into SAS and executed, so anybody answering your question has something to work on and doesn't have to bother with inventing test data. Or -if the problem is getting data into SAS, - then attach a CSV or TXT file, not Excel, because most people wouldn't&amp;nbsp; dare to open Excel files from unknown sources.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So far there are too many initial questions, like&lt;/P&gt;
&lt;P&gt;Do you have a SAS input or a LOG file?&lt;/P&gt;
&lt;P&gt;What is the time stamp, a datetime numeric value, a string like '2020-01-02:12:59:03.021' or .. ?&lt;/P&gt;
&lt;P&gt;How is the boolean value represented, Literal True/False (or true/false or TRUE/FALSE), 0/1 or .. ?&lt;/P&gt;
&lt;P&gt;Is it any change of state from one record to the next, or changes applying to a given ID of some kind?&lt;/P&gt;
&lt;P&gt;is the initial state in the log file considered a change?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You have given a pretty good explanation of how the problen should be solved, but the SAS vocabulary is different, and the syntax reflects that.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The following is the most simple version one could imagine. Common vocabulary is added in parentheses. Note that&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;the output data set is specified in the d&lt;EM&gt;ata&lt;/EM&gt; statement.&lt;/LI&gt;
&lt;LI&gt;the output data step includes per default all variables (columns) from the input + any variables created in the step, in this case zero.&lt;/LI&gt;
&lt;LI&gt;the input data set (table) is specified in the &lt;EM&gt;set&lt;/EM&gt; statement, and the scope is per default all observations (records)&lt;/LI&gt;
&lt;LI&gt;the data step loops per default over the input data set, so all observations are read sequentially.&lt;/LI&gt;
&lt;LI&gt;the&lt;EM&gt;&amp;nbsp;if&lt;/EM&gt;&amp;nbsp;statement used without a corresponding &lt;EM&gt;then&lt;/EM&gt; is called a subsetting if, and output (commit) is performed only when the given condition is met in the current observation.&lt;/LI&gt;
&lt;LI&gt;the &lt;EM&gt;if&lt;/EM&gt; statement is executed once pr. input observarion because of the implicit loop.&lt;/LI&gt;
&lt;LI&gt;the &lt;EM&gt;lag&lt;/EM&gt; function returns a missing value (NULL value) for the first observation, because there is no previous observation to read from.&lt;/LI&gt;
&lt;LI&gt;the run statement terminates the data step and thereby also the implicit loop.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;* Data Step with CARD input - 
  to read a log file use an infile statement instead of datalines;
data have;
	length timestamp 8 state $5;
	input timestamp datetime22.3 @24 state $5.;
	format timestamp datetime22.3;
	datalines;
25DEC2020:05:53:55.256 True
25DEC2020:11:47:49.512 True
25DEC2020:17:41:43.768 True
25DEC2020:23:35:38.024 False
26DEC2020:05:29:32.280 False
26DEC2020:11:23:26.536 False
26DEC2020:17:17:20.792 False
26DEC2020:23:11:15.048 False
27DEC2020:05:05:09.304 False
27DEC2020:10:59:03.560 False
27DEC2020:16:52:57.816 False
27DEC2020:22:46:52.072 True
28DEC2020:04:40:46.328 True
28DEC2020:10:34:40.584 True
28DEC2020:16:28:34.840 True
28DEC2020:22:22:29.096 False
29DEC2020:04:16:23.352 False
29DEC2020:10:10:17.608 False
29DEC2020:16:04:11.864 False
29DEC2020:21:58:06.120 False
;
run;

* Keep records where state is changed 
  - the shortest possible version, current state is compared to state from previous record;
data want; 
	set have;
	if state ne lag(state);
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;output data set contains:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="state.gif" style="width: 290px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/35112i32131A1FDFBDCF95/image-size/large?v=v2&amp;amp;px=999" role="button" title="state.gif" alt="state.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>Thu, 02 Jan 2020 12:52:18 GMT</pubDate>
    <dc:creator>ErikLund_Jensen</dc:creator>
    <dc:date>2020-01-02T12:52:18Z</dc:date>
    <item>
      <title>Looping trough tabel and detect change value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/614717#M179772</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm not new to programming but I am new to SAS and I want to perform a simple task on a table but can not find a clear answer:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have a table with multiple columns which is the result of a logfile of a system. For analyses I'm only interested in a value change in one&amp;nbsp; specific column. If the value of this column changes from False to True or vice versa THEN I want to place the row, wich contains the timestamp to a specific table. The next value change is then added to the specific table.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Normaly I would build a loop and store the last know value of the column and compare each itration with that value and commit the data to a specific table. Now in SAS I need some help to get started.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 02 Jan 2020 09:38:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/614717#M179772</guid>
      <dc:creator>Retep1972</dc:creator>
      <dc:date>2020-01-02T09:38:25Z</dc:date>
    </item>
    <item>
      <title>Re: Looping trough tabel and detect change value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/614735#M179774</link>
      <description>&lt;P&gt;In a data step, use the lag() function to retrieve the value from the preceding observation.&lt;/P&gt;</description>
      <pubDate>Thu, 02 Jan 2020 11:45:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/614735#M179774</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2020-01-02T11:45:39Z</dc:date>
    </item>
    <item>
      <title>Re: Looping trough tabel and detect change value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/614744#M179778</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/305287"&gt;@Retep1972&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Welcome in this universe of nerds! It is good practice here to give some additional information, like code to create example input that can be copied into SAS and executed, so anybody answering your question has something to work on and doesn't have to bother with inventing test data. Or -if the problem is getting data into SAS, - then attach a CSV or TXT file, not Excel, because most people wouldn't&amp;nbsp; dare to open Excel files from unknown sources.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So far there are too many initial questions, like&lt;/P&gt;
&lt;P&gt;Do you have a SAS input or a LOG file?&lt;/P&gt;
&lt;P&gt;What is the time stamp, a datetime numeric value, a string like '2020-01-02:12:59:03.021' or .. ?&lt;/P&gt;
&lt;P&gt;How is the boolean value represented, Literal True/False (or true/false or TRUE/FALSE), 0/1 or .. ?&lt;/P&gt;
&lt;P&gt;Is it any change of state from one record to the next, or changes applying to a given ID of some kind?&lt;/P&gt;
&lt;P&gt;is the initial state in the log file considered a change?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You have given a pretty good explanation of how the problen should be solved, but the SAS vocabulary is different, and the syntax reflects that.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The following is the most simple version one could imagine. Common vocabulary is added in parentheses. Note that&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;the output data set is specified in the d&lt;EM&gt;ata&lt;/EM&gt; statement.&lt;/LI&gt;
&lt;LI&gt;the output data step includes per default all variables (columns) from the input + any variables created in the step, in this case zero.&lt;/LI&gt;
&lt;LI&gt;the input data set (table) is specified in the &lt;EM&gt;set&lt;/EM&gt; statement, and the scope is per default all observations (records)&lt;/LI&gt;
&lt;LI&gt;the data step loops per default over the input data set, so all observations are read sequentially.&lt;/LI&gt;
&lt;LI&gt;the&lt;EM&gt;&amp;nbsp;if&lt;/EM&gt;&amp;nbsp;statement used without a corresponding &lt;EM&gt;then&lt;/EM&gt; is called a subsetting if, and output (commit) is performed only when the given condition is met in the current observation.&lt;/LI&gt;
&lt;LI&gt;the &lt;EM&gt;if&lt;/EM&gt; statement is executed once pr. input observarion because of the implicit loop.&lt;/LI&gt;
&lt;LI&gt;the &lt;EM&gt;lag&lt;/EM&gt; function returns a missing value (NULL value) for the first observation, because there is no previous observation to read from.&lt;/LI&gt;
&lt;LI&gt;the run statement terminates the data step and thereby also the implicit loop.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;* Data Step with CARD input - 
  to read a log file use an infile statement instead of datalines;
data have;
	length timestamp 8 state $5;
	input timestamp datetime22.3 @24 state $5.;
	format timestamp datetime22.3;
	datalines;
25DEC2020:05:53:55.256 True
25DEC2020:11:47:49.512 True
25DEC2020:17:41:43.768 True
25DEC2020:23:35:38.024 False
26DEC2020:05:29:32.280 False
26DEC2020:11:23:26.536 False
26DEC2020:17:17:20.792 False
26DEC2020:23:11:15.048 False
27DEC2020:05:05:09.304 False
27DEC2020:10:59:03.560 False
27DEC2020:16:52:57.816 False
27DEC2020:22:46:52.072 True
28DEC2020:04:40:46.328 True
28DEC2020:10:34:40.584 True
28DEC2020:16:28:34.840 True
28DEC2020:22:22:29.096 False
29DEC2020:04:16:23.352 False
29DEC2020:10:10:17.608 False
29DEC2020:16:04:11.864 False
29DEC2020:21:58:06.120 False
;
run;

* Keep records where state is changed 
  - the shortest possible version, current state is compared to state from previous record;
data want; 
	set have;
	if state ne lag(state);
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;output data set contains:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="state.gif" style="width: 290px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/35112i32131A1FDFBDCF95/image-size/large?v=v2&amp;amp;px=999" role="button" title="state.gif" alt="state.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>Thu, 02 Jan 2020 12:52:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/614744#M179778</guid>
      <dc:creator>ErikLund_Jensen</dc:creator>
      <dc:date>2020-01-02T12:52:18Z</dc:date>
    </item>
    <item>
      <title>Re: Looping trough tabel and detect change value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/619513#M181912</link>
      <description>&lt;P&gt;I have been trying to get it to work but I got stuk with the creation of the "have" data. I'm using the code below:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;*data set you want to create demo data for;&lt;BR /&gt;%let dataSetName = filter_for_data1;&lt;BR /&gt;*number of observations you want to keep;&lt;BR /&gt;%let obsKeep = 100;&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;******************************************************&lt;BR /&gt;DO NOT CHANGE ANYTHING BELOW THIS LINE&lt;BR /&gt;******************************************************;&lt;/P&gt;&lt;P&gt;%let source_path = &lt;A href="https://gist.githubusercontent.com/statgeek/bcc55940dd825a13b9c8ca40a904cba9/raw/865d2cf18f5150b8e887218dde0fc3951d0ff15b/data2datastep.sas" target="_blank"&gt;https://gist.githubusercontent.com/statgeek/bcc55940dd825a13b9c8ca40a904cba9/raw/865d2cf18f5150b8e887218dde0fc3951d0ff15b/data2datastep.sas&lt;/A&gt;;&lt;/P&gt;&lt;P&gt;filename reprex url "&amp;amp;source_path";&lt;BR /&gt;%include reprex;&lt;BR /&gt;filename reprex;&lt;/P&gt;&lt;P&gt;option linesize=max;&lt;BR /&gt;%data2datastep(dsn=&amp;amp;dataSetName, file=have, obs=&amp;amp;obsKeep);&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;data work.want;&lt;BR /&gt;set work.have;&lt;BR /&gt;if value ne lag(value);&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;It wil not create the work.have data and I'm a bit clueless since I think I'm using the right variables. As attachement the log file&lt;/P&gt;</description>
      <pubDate>Thu, 23 Jan 2020 14:13:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/619513#M181912</guid>
      <dc:creator>Retep1972</dc:creator>
      <dc:date>2020-01-23T14:13:46Z</dc:date>
    </item>
    <item>
      <title>Re: Looping trough tabel and detect change value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/619558#M181937</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/305287"&gt;@Retep1972&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;First a tip: If you reply to somebody then use the&amp;nbsp;@ notation as shown above. I only read your reply by chance, because I never got a notification.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;According to the log, test data is written to a data set named&amp;nbsp;&lt;EM&gt;FILTER_FOR_ODS_SLS_DEL1&lt;/EM&gt;. I am not a SAS EG user, but I guess the name is given by default by EG like &lt;EM&gt;QUERY_FOR_something&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The following data step will not work, because it tries to read data set named &lt;EM&gt;have,&lt;/EM&gt;&amp;nbsp;which is never created.&amp;nbsp;So instead of &lt;EM&gt;have&lt;/EM&gt; you need to specify the actual name of the data set containing your test data.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Another tip: You can use the automatic variable &amp;amp;SYSLAST instead of a literal name to refer to the most recently created data set:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data work.want;
	set &amp;amp;syslast;
	if value ne lag(value);
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 23 Jan 2020 15:35:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/619558#M181937</guid>
      <dc:creator>ErikLund_Jensen</dc:creator>
      <dc:date>2020-01-23T15:35:07Z</dc:date>
    </item>
    <item>
      <title>Re: Looping trough tabel and detect change value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/619774#M182037</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;&lt;/P&gt;&lt;P&gt;I have no use for a "have" data set but I thought I needed it as an input for the lag function but the "&amp;amp;syslast" was the key to solve my problem! Thank you!&lt;/P&gt;</description>
      <pubDate>Fri, 24 Jan 2020 07:13:21 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/619774#M182037</guid>
      <dc:creator>Retep1972</dc:creator>
      <dc:date>2020-01-24T07:13:21Z</dc:date>
    </item>
    <item>
      <title>Re: Looping trough tabel and detect change value</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/619775#M182038</link>
      <description>&lt;P&gt;"have" and "want" are the names we use for datasets in code examples, so it is clear what is the source and what the target. Replace those names with your actual dataset names.&lt;/P&gt;</description>
      <pubDate>Fri, 24 Jan 2020 07:06:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Looping-trough-tabel-and-detect-change-value/m-p/619775#M182038</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2020-01-24T07:06:08Z</dc:date>
    </item>
  </channel>
</rss>

