<?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 Efficiently Adding a Shifted Date Column to a Large SAS Dataset in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962788#M375204</link>
    <description>&lt;P&gt;Dear All,&lt;/P&gt;&lt;P&gt;I have a large dataset stored on a remote SAS server with approximately 400 million rows and 88 columns. My goal is to create a new column by shifting a date variable by 1 month. I intend to do this with a simple left join, similar to what I would do in a SQL server.&lt;/P&gt;&lt;P&gt;My problem is as follows: when I tried to use the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ALTER TABLE&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;command, it ran indefinitely without producing any results. However, when I created a new table, the process finished in 30 minutes. How should I properly execute this process?&lt;/P&gt;&lt;P&gt;Here is the hard-copy version of my code:&lt;/P&gt;&lt;PRE&gt;rsubmit;
%let start_time = %sysfunc(datetime());

proc sql;
drop table table_v2;
create table table_v2 as
select *,
t2.variable as shifted_variable
from table_v1 as t1
left join (select date, deal_id, variable from table_v1) as t2
on t1.deal_id = t2.deal_id and t1.date = intnx('month', t2.date, -1, 'E')
order by t1.deal_id, t1.date;
quit;

%let end_time = %sysfunc(datetime());
%let duration = %sysevalf(&amp;amp;end_time - &amp;amp;start_time);
%put NOTE: The query took &amp;amp;duration seconds to run.;
endrsubmit;&lt;/PRE&gt;&lt;P&gt;Thank you for your assistance!&lt;/P&gt;&lt;P&gt;Gabor&lt;/P&gt;</description>
    <pubDate>Thu, 27 Mar 2025 13:21:56 GMT</pubDate>
    <dc:creator>abigel</dc:creator>
    <dc:date>2025-03-27T13:21:56Z</dc:date>
    <item>
      <title>Efficiently Adding a Shifted Date Column to a Large SAS Dataset</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962788#M375204</link>
      <description>&lt;P&gt;Dear All,&lt;/P&gt;&lt;P&gt;I have a large dataset stored on a remote SAS server with approximately 400 million rows and 88 columns. My goal is to create a new column by shifting a date variable by 1 month. I intend to do this with a simple left join, similar to what I would do in a SQL server.&lt;/P&gt;&lt;P&gt;My problem is as follows: when I tried to use the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;ALTER TABLE&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;command, it ran indefinitely without producing any results. However, when I created a new table, the process finished in 30 minutes. How should I properly execute this process?&lt;/P&gt;&lt;P&gt;Here is the hard-copy version of my code:&lt;/P&gt;&lt;PRE&gt;rsubmit;
%let start_time = %sysfunc(datetime());

proc sql;
drop table table_v2;
create table table_v2 as
select *,
t2.variable as shifted_variable
from table_v1 as t1
left join (select date, deal_id, variable from table_v1) as t2
on t1.deal_id = t2.deal_id and t1.date = intnx('month', t2.date, -1, 'E')
order by t1.deal_id, t1.date;
quit;

%let end_time = %sysfunc(datetime());
%let duration = %sysevalf(&amp;amp;end_time - &amp;amp;start_time);
%put NOTE: The query took &amp;amp;duration seconds to run.;
endrsubmit;&lt;/PRE&gt;&lt;P&gt;Thank you for your assistance!&lt;/P&gt;&lt;P&gt;Gabor&lt;/P&gt;</description>
      <pubDate>Thu, 27 Mar 2025 13:21:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962788#M375204</guid>
      <dc:creator>abigel</dc:creator>
      <dc:date>2025-03-27T13:21:56Z</dc:date>
    </item>
    <item>
      <title>Re: Efficiently Adding a Shifted Date Column to a Large SAS Dataset</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962806#M375212</link>
      <description>&lt;P&gt;Welcome&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/474461"&gt;@abigel&lt;/a&gt;&amp;nbsp;to the sas support community:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;you&amp;nbsp;wrote:&lt;/P&gt;
&lt;P&gt;However, when I created a new table, the process finished in 30 minutes. How should I properly execute this process?&lt;/P&gt;
&lt;P&gt;I would use the new table creation process.&amp;nbsp; It's simply faster.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As to why this is the case, I write the below as a non-expert in PROC SQL:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;I wonder if the ALTER process "modifies" one row at a time, as opposed to writing a collection of rows when creating a new table.&amp;nbsp; That is, perhaps it utilizes much more input/output resources.&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;Also&amp;nbsp; a question,&amp;nbsp; Does your current table have integrity constraints defined?&amp;nbsp; If so, then note from&amp;nbsp;&lt;A style="font-family: inherit; background-color: #ffffff;" href="https://support.sas.com/documentation/cdl/en/sqlproc/62086/HTML/default/viewer.htm#a001396785.htm" target="_self"&gt;Creating and Using Integrity Constraints in a Table&lt;/A&gt;&lt;SPAN&gt;:&amp;nbsp; (&lt;EM&gt;&lt;STRONG&gt;italics&lt;/STRONG&gt;&lt;/EM&gt; mine)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;"&lt;SPAN&gt;Integrity constraints are rules that you specify to guarantee the accuracy, completeness, or consistency of data in tables. &lt;EM&gt;&lt;STRONG&gt;All integrity constraints are enforced when you insert, delete, or alter data values in the columns of a table for which integrity constraints have been defined.&lt;/STRONG&gt;&lt;/EM&gt; Before a constraint is added to a table that contains existing data, all the data is checked to determine that it satisfies the constraints."&lt;/SPAN&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;This suggests to me that the ALTER statement would need to allocate time to apply those integrity constraints in modifying every observation in the table.&amp;nbsp; OTOH, I presume that making a new table would not automatically do so using the code you have shown.&amp;nbsp;&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;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 27 Mar 2025 19:37:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962806#M375212</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2025-03-27T19:37:05Z</dc:date>
    </item>
    <item>
      <title>Re: Efficiently Adding a Shifted Date Column to a Large SAS Dataset</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962807#M375213</link>
      <description>&lt;P&gt;&lt;SPAN&gt;In addition to the integrity constraints mentioned by&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/31461"&gt;@mkeintz&lt;/a&gt;, indexes on the table may also require modification. So, a couple of questions:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;1. Is your data in a SAS data set, or is it stored in a database table accessed via a SAS/ACCESS LIBNAME engine?&lt;BR /&gt;&amp;nbsp; If so, the INTNX function cannot be passed to the database. This means that the entire table would have to be pulled out into SAS, the data modified, then copied back into the database. Depending on bandwidth and server co-location issues, this could really choke your performance.&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;2. Does the table have indexes or integrity constraints defined?&lt;BR /&gt;&amp;nbsp; If so, consider dropping the indexes before updating and re-buliding them after the update is complete.&lt;BR /&gt;&lt;BR /&gt;If this is a SAS dataset in a SAS library, consider using DATA step processing instead. Something like this:&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Create some data to experiment with */
data mylib.have;
	length deal_id date variable 8;
	format deal_id z4. date variable yymmddd10.;
	drop _:;
	retain deal_id 100;
	do _m=1 to 12 by 2;
		do _d=1 to 31 by 3;
			date=mdy(_m,_d,2024);
			if not _error_ then do;
				variable=date;
				output;
			end;
		end;
	end;
run;

title "MYLIB.HAVE - Before mods";
proc print data=mylib.have(obs=5);run;

/* If you can, create both data sets in the same library: */

/* Add the new column, write out to a new data set */
data mylib.want;
	set mylib.have;
	format shifted_variable yymmddd10.;
	shifted_variable=intnx('month', date, -1, 'E');
run;

proc datasets library=mylib nolist nodetails;
   /* The, delete the original */
	delete have;
run;
   /* And rename the new data set with the original data set's name */
	change want=have;
run; quit;

title "MYLIB.HAVE - After mods";
proc print data=mylib.have(obs=5);run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV class="branch"&gt;&lt;A name="IDX" target="_blank"&gt;&lt;/A&gt;
&lt;TABLE class="systitleandfootercontainer" border="0" summary="Page Layout" width="100%" frame="void" rules="none" cellspacing="1" cellpadding="1"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="l systemtitle"&gt;MYLIB.HAVE - Before mods&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;BR /&gt;
&lt;DIV&gt;
&lt;DIV align="left"&gt;
&lt;TABLE class="table" summary="Procedure Print: Data Set MYLIB.HAVE" frame="box" rules="all" cellspacing="0" cellpadding="5"&gt;&lt;COLGROUP&gt; &lt;COL /&gt;&lt;/COLGROUP&gt; &lt;COLGROUP&gt; &lt;COL /&gt; &lt;COL /&gt; &lt;COL /&gt;&lt;/COLGROUP&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH class="r header" scope="col"&gt;Obs&lt;/TH&gt;
&lt;TH class="r header" scope="col"&gt;deal_id&lt;/TH&gt;
&lt;TH class="r header" scope="col"&gt;date&lt;/TH&gt;
&lt;TH class="r header" scope="col"&gt;variable&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;1&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-01&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-01&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;2&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-04&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-04&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;3&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-07&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-07&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;4&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-10&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-10&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;5&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-13&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-13&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="branch"&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;HR size="3" /&gt;&lt;A name="IDX1" target="_blank"&gt;&lt;/A&gt;
&lt;TABLE class="systitleandfootercontainer" border="0" summary="Page Layout" width="100%" frame="void" rules="none" cellspacing="1" cellpadding="1"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="l systemtitle"&gt;MYLIB.HAVE - After mods&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;BR /&gt;
&lt;DIV&gt;
&lt;DIV align="left"&gt;
&lt;TABLE class="table" summary="Procedure Print: Data Set MYLIB.HAVE" frame="box" rules="all" cellspacing="0" cellpadding="5"&gt;&lt;COLGROUP&gt; &lt;COL /&gt;&lt;/COLGROUP&gt; &lt;COLGROUP&gt; &lt;COL /&gt; &lt;COL /&gt; &lt;COL /&gt; &lt;COL /&gt;&lt;/COLGROUP&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH class="r header" scope="col"&gt;Obs&lt;/TH&gt;
&lt;TH class="r header" scope="col"&gt;deal_id&lt;/TH&gt;
&lt;TH class="r header" scope="col"&gt;date&lt;/TH&gt;
&lt;TH class="r header" scope="col"&gt;variable&lt;/TH&gt;
&lt;TH class="r header" scope="col"&gt;shifted_variable&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;1&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-01&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-01&lt;/TD&gt;
&lt;TD class="r data"&gt;2023-12-31&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;2&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-04&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-04&lt;/TD&gt;
&lt;TD class="r data"&gt;2023-12-31&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;3&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-07&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-07&lt;/TD&gt;
&lt;TD class="r data"&gt;2023-12-31&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;4&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-10&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-10&lt;/TD&gt;
&lt;TD class="r data"&gt;2023-12-31&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TH class="r rowheader" scope="row"&gt;5&lt;/TH&gt;
&lt;TD class="r data"&gt;0100&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-13&lt;/TD&gt;
&lt;TD class="r data"&gt;2024-01-13&lt;/TD&gt;
&lt;TD class="r data"&gt;2023-12-31&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;BR /&gt;If your SAS data set had indexes or integrity constraints, they will have been deleted by the DATA step process. You can rebuild them on the new dataset using the PROC DATASETS &lt;A href="https://go.documentation.sas.com/doc/en/pgmsascdc/default/proc/p03h320ajtd062n1d05vyoqso4yo.htm" target="_self"&gt;INDEX CREATE&lt;/A&gt;&amp;nbsp;and &lt;A href="https://go.documentation.sas.com/doc/en/pgmsascdc/default/proc/p16uvvbluwnpwun1n74x9odgg9r9.htm" target="_self"&gt;IC CREATE&lt;/A&gt; statements.&amp;nbsp;&lt;BR /&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 27 Mar 2025 20:02:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962807#M375213</guid>
      <dc:creator>SASJedi</dc:creator>
      <dc:date>2025-03-27T20:02:36Z</dc:date>
    </item>
    <item>
      <title>Re: Efficiently Adding a Shifted Date Column to a Large SAS Dataset</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962808#M375214</link>
      <description>&lt;P&gt;Is this a SAS dataset we are talking about?&lt;/P&gt;
&lt;P&gt;Don't use ALTER TABLE.&amp;nbsp; That will make a NEW dataset.&amp;nbsp; Then you will have push individual values into individual observations (think counting grains of sand or replacing all of the orange grains of sand with yellow grains).&amp;nbsp;&amp;nbsp;&lt;A href="https://en.wikipedia.org/wiki/File:Asynchronous_Syntropy.jpg" target="_blank"&gt;https://en.wikipedia.org/wiki/File:Asynchronous_Syntropy.jpg&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Instead just run a step to make the new dataset.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;And if by "shift" you just mean remember the previous value then the step is almost trivial.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
  set have;
  by deal_id date;
  shifted_variable=lag(variable);
  if first.deal_id then call missing(shifted_variable);
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 27 Mar 2025 23:45:59 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962808#M375214</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2025-03-27T23:45:59Z</dc:date>
    </item>
    <item>
      <title>Re: Efficiently Adding a Shifted Date Column to a Large SAS Dataset</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962812#M375217</link>
      <description>&lt;P&gt;Performance is fickle and depends on the data and how you use it.&lt;/P&gt;
&lt;P&gt;ALTER creates a new data set, and isn't usually faster than CREATE, but it depends..&lt;/P&gt;
&lt;P&gt;SQL does things in a different way, and can also exhibit slowness compared to data steps. SAS has really tuned these over the years.&lt;/P&gt;
&lt;P&gt;Consider this:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data TEST1 TEST2 TEST3; 
  do I=1 to 5e7;
    output;
  end;
run;
 
 
proc sql; %*** 4.1 seconds ***;
  alter table TEST1 add J int;
quit;
 
  
proc sql; %*** 4.7 seconds ***;
  create table TEST2 as select *, . as J from TEST2 ;
quit; 
 

data TEST3; %*** 2.7 seconds ***;
  set TEST3; 
  retain J .;
run;
   &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;A data step is fastest here, CREATE takes 70% more time. ALTER is in the middle.&lt;/P&gt;
&lt;P&gt;I ran that code on SAS ODA btw.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Bottom line: You'll build a feel for what methods work best for different tasks, but when performance becomes important, nothing replaces bench-marking your processes with your data on your hardware.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 29 Mar 2025 04:03:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962812#M375217</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2025-03-29T04:03:06Z</dc:date>
    </item>
    <item>
      <title>Re: Efficiently Adding a Shifted Date Column to a Large SAS Dataset</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962868#M375222</link>
      <description>&lt;P&gt;Hello&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/474461"&gt;@abigel&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You know your data best and also what the next steps will be after adding that "shifted date column" to the large dataset.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;That said, looking at your code and running it against simple test data (see further below), there are a couple of things I noticed suggesting that aiming at a different result (e.g., a &lt;EM&gt;separate&lt;/EM&gt; rather than augmented dataset) might be more efficient than your current approach:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Contrary to what your subject line suggests, the added column does not contain values of variable DATE, but values of variable VARIABLE.&lt;/LI&gt;
&lt;LI&gt;I would expect a significant portion of the values of the newly added column to be &lt;EM&gt;trivially missing:&lt;/EM&gt;&amp;nbsp;all observations with DATE values other than end-of-month dates. This is a consequence of your left join involving the ON condition&amp;nbsp;&lt;BR /&gt;
&lt;PRE&gt;t1.date = intnx('month', t2.date, -1, 'E')&lt;/PRE&gt;
&lt;/LI&gt;
&lt;LI&gt;Given that the existing dataset is so large, it seems questionable to me that your code has the potential of adding lots of (copied)&amp;nbsp;&lt;EM&gt;observations&lt;/EM&gt; ("rows") to it, not just a derived variable ("column"). In a simple test dataset with four years' worth of data per DEAL_ID and one observation per day the number of observations almost &lt;EM&gt;doubled&lt;/EM&gt;&amp;nbsp;(see below)&lt;FONT face="arial,helvetica,sans-serif"&gt;:&lt;/FONT&gt; For each DEAL_ID and year, the left join inserted 27 (in leap years: 28) copies of the observation of January 31st in order to accommodate the 28 (or 29, resp.) values of VARIABLE from the subsequent February. Similarly, the resulting dataset contained 31 observations (per DEAL_ID and year) for February 28th (or 29th, resp.) -- all identical except for the newly added SHIFTED_VARIABLE (containing March VARIABLE values), and so on. Consider the amount of redundancy with your real 88-variables dataset!&lt;/LI&gt;
&lt;LI&gt;With more than one observation per end-of-month date even more redundant information would be generated (unless there were fewer than two observations from the subsequent month), as &lt;EM&gt;each&lt;/EM&gt; of those observations would be copied so many times as described above.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*  Create simplified test data */

data have;
call streaminit(27182818);
do deal_id=1 to 3;
  do date='01JAN2021'd to '31DEC2024'd;
    v=rand('integer',100,999);
    x=rand('uniform');
    output;
  end;
end;
format date date9.;
run; /* 4383 obs. */

/* Perform the original left join */

proc sql;
create table result as
select t1.*, t2.v as shifted_v
from have as t1
left join (select date, deal_id, v from have) as t2
on t1.deal_id = t2.deal_id and t1.date = intnx('month', t2.date, -1, 'E')
order by t1.deal_id, t1.date;
quit; /* 8532 obs. */&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 28 Mar 2025 18:52:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Efficiently-Adding-a-Shifted-Date-Column-to-a-Large-SAS-Dataset/m-p/962868#M375222</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2025-03-28T18:52:12Z</dc:date>
    </item>
  </channel>
</rss>

