<?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: Changing from Long to Wide dataset involving array variables in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840747#M332426</link>
    <description>&lt;P&gt;I am thinking of something like below macro code:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;options mprint mlogic;
%macro getArrayData(old,numvars);
data have1;
%do _index=1 %to 3 until(last.id);
	set &amp;amp;old;
	by id;
	/** index i starts at 2 because the first variable is the ID **/
	%do i=2 %to 1000;
	/** add suffix _var to each variable and make it an array of length 3 **/
       array %scan(&amp;amp;var_list,&amp;amp;i.)_var {3};     ;
	%end;
	%if time1 = time %then %do;
	/** Loop through 1000 vriable names stored in macrovariable var_list **/
		%do j=2 %to 1000;
		/** add suffix _var to current variable and take the first element **/
			%scan(&amp;amp;var_list,&amp;amp;j.)_var {1}=%scan(&amp;amp;var_list,&amp;amp;j.);
		%end;
	%end;
	%else %if time2 = time %then %do;
		%do k=2 %to 1000;
		/** add suffix _var to current variable and take the second element **/
			%scan(&amp;amp;var_list,&amp;amp;k.)_var {2}=%scan(&amp;amp;var_list,&amp;amp;k.);
		%end;
	%end;
	%else %if time3 = time %then %do;
		%do n=1 %to 1000;
		/** add suffix _var to current variable and take the third element **/
			%scan(&amp;amp;var_list,&amp;amp;n.)_var {3}=%scan(&amp;amp;var_list,&amp;amp;n.);
		%end;

	%end;
%mend getArrayData;&lt;/PRE&gt;
&lt;P&gt;One simplification I can make is that in Dataset Old and Have1, time can only ever be 10,11 or 12.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;data Old;
  input ID time a;
datalines;
999 10 3
999 11  .
999 12 4
99  10 5
99  11 .
99  12 .
;&lt;BR /&gt;run;&lt;/PRE&gt;
&lt;PRE class="language-sas"&gt;&lt;CODE&gt;data have1;
  input ID a1-a3 time1-time3;
datalines;
 99 . . . 1 2 3
 99 . . . 10 11 12
999 . . . 1 2 3
999 . . . 10 11 12
;&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Wed, 26 Oct 2022 04:51:24 GMT</pubDate>
    <dc:creator>nstdt</dc:creator>
    <dc:date>2022-10-26T04:51:24Z</dc:date>
    <item>
      <title>Changing from Long to Wide dataset involving array variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840733#M332419</link>
      <description>&lt;P&gt;Hi all,&lt;/P&gt;
&lt;P&gt;I have two data sets:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;1)&amp;nbsp;&lt;STRONG&gt;&lt;EM&gt;have1&lt;/EM&gt;&lt;/STRONG&gt;&amp;nbsp; with variables names occurring in series: a1,a2,a3, time1,time2,time3. The "a"s are all empty. I can't go back and make any changes in the code used to create this dataset.&lt;/P&gt;
&lt;P&gt;and&amp;nbsp;&lt;/P&gt;
&lt;P&gt;2) &lt;EM&gt;&lt;STRONG&gt;Old&lt;/STRONG&gt;&lt;/EM&gt;&amp;nbsp; which has the values for the "a" variables but in "Long" format&lt;/P&gt;
&lt;P&gt;I need to create a new dataset &lt;EM&gt;&lt;STRONG&gt;have1&lt;/STRONG&gt;&lt;/EM&gt;&amp;nbsp;in such a way that I can get the "a" variable from &lt;EM&gt;&lt;STRONG&gt;Old&lt;/STRONG&gt;&lt;/EM&gt; . How can I do this?&lt;/P&gt;
&lt;P&gt;Here is some sample data:&lt;/P&gt;
&lt;PRE&gt;##  dataset with ID variable and time variables  filled and "a" variables empty  

data have1;
 input ID a1 a2 a3 time1 time2 time3;
 datalines;
 99 . . . 1 2 3
 99 . . . 10 11 12
 999 . . . 1 2 3
 999 . . . 10 11 12
 ;
 run;

## dataset with ID, Time and "a" variable in rows
data Old;
input ID  time a;
datalines;
999 10 3
999 11  .
999 12 4
99  10 5
99   1 .
;
run;
## I want to pull in the "a" variable from Old based on the "time" variable&lt;BR /&gt;## This will change the Long dataset Old to the Wide dataset have1
data have1;
do i=1 to 3 until (last.ID);
		set Old;
		by ID;
		if time[i]=time then a[i] = a;
	end;
 run;&lt;/PRE&gt;
&lt;P&gt;Thank you!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 26 Oct 2022 01:51:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840733#M332419</guid>
      <dc:creator>nstdt</dc:creator>
      <dc:date>2022-10-26T01:51:11Z</dc:date>
    </item>
    <item>
      <title>Re: Changing from Long to Wide dataset involving array variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840734#M332420</link>
      <description>&lt;P&gt;If you want to process the data by ID then make sure it is sorted by ID.&lt;/P&gt;
&lt;P&gt;Your example HAVE1 dataset has the repeated measures order by TIME also so I would include that in the sort order.&lt;/P&gt;
&lt;P&gt;You have to DEFINE an array before you can use.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It saves a lot of code when defining a array of variable with numeric suffixes if the array name is the same as the basename of the variable being referenced by the array.&amp;nbsp; So let's rename your input variables to get them out of the way so we can use the basename as the name of the array.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data Old;
  input ID time a;
datalines;
999 10 3
999 11  .
999 12 4
99  10 5
99   1 .
;

proc sort data=old;
  by id time;
run;

data want;
  do _index=1 to 3 until(last.id);
    set old (rename=(time=_time a=_a));
    by id ;
    array a[3];
    array time[3];
    a[_index]=_a;
    time[_index]=_time;
  end;
  drop _: ;
run;

proc print;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;PRE&gt;Obs     ID    a1    a2    a3    time1    time2    time3

 1      99     .     5     .       1       10        .
 2     999     3     .     4      10       11       12

&lt;/PRE&gt;
&lt;P&gt;&lt;STRONG&gt;So your OLD dataset does NOT have the same information as your posted HAVE1 dataset.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Did you expect that they would?&amp;nbsp; If so then you need provide more rules for how to construct the new dataset.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you want to recreate the HAVE1 data with the A values from OLD inserted then it seems easier to convert HAVE1 to TALL structure and merge.&amp;nbsp; You can then convert back to the WIDE structure if you want.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have1;
  input ID a1-a3 time1-time3;
datalines;
 99 . . . 1 2 3
 99 . . . 10 11 12
999 . . . 1 2 3
999 . . . 10 11 12
;

data tall ;
  set have1;
  array time[3];
  do index=1 to dim(time);
    _time = time[index];
    output;
  end;
  keep id _time;
run;

data fixed ;
  merge tall old(rename=(time=_time a=_a));
  by id _time;
run;

data want;
  do _index=1 to 3 until(last.id);
    set fixed ;
    by id ;
    array a[3];
    array time[3];
    a[_index]=_a;
    time[_index]=_time;
  end;
  drop _: ;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Result:&lt;/P&gt;
&lt;PRE&gt;Obs     ID    a1    a2    a3    time1    time2    time3

 1      99     .     .     .       1        2        3
 2      99     5     .     .      10       11       12
 3     999     .     .     .       1        2        3
 4     999     3     .     4      10       11       12
&lt;/PRE&gt;</description>
      <pubDate>Wed, 26 Oct 2022 02:22:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840734#M332420</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2022-10-26T02:22:45Z</dc:date>
    </item>
    <item>
      <title>Re: Changing from Long to Wide dataset involving array variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840744#M332424</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;Thanks for your reply. It is not necessary for Old to have the same information as Have1 - just that Old has the A values a well as ID but Have1 does not. I can't make both datasets Tall - that's because the specific purpose of this code is to create a Wide dataset to manage further data processing.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;Is it possible to automate using macros the steps where you create arrays in Want- where you declare 'array a' and 'array time'? This is what I tried but couldn't do - I actually have about a 1000 variables, not just A. Let us say I have the variable names, all 1000, stored in a macro-variable. How could I call a macro to create arrays within the data step when you create Data Want?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks.&lt;/P&gt;
&lt;PRE class="language-sas"&gt;&lt;CODE&gt;data want;
  do _index=1 to 3 until(last.id);
    set old (rename=(time=_time a=_a));
    by id ;
    array a[3];
    array time[3];
    a[_index]=_a;
    time[_index]=_time;
  end;
  drop _: ;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 26 Oct 2022 04:17:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840744#M332424</guid>
      <dc:creator>nstdt</dc:creator>
      <dc:date>2022-10-26T04:17:35Z</dc:date>
    </item>
    <item>
      <title>Re: Changing from Long to Wide dataset involving array variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840747#M332426</link>
      <description>&lt;P&gt;I am thinking of something like below macro code:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;options mprint mlogic;
%macro getArrayData(old,numvars);
data have1;
%do _index=1 %to 3 until(last.id);
	set &amp;amp;old;
	by id;
	/** index i starts at 2 because the first variable is the ID **/
	%do i=2 %to 1000;
	/** add suffix _var to each variable and make it an array of length 3 **/
       array %scan(&amp;amp;var_list,&amp;amp;i.)_var {3};     ;
	%end;
	%if time1 = time %then %do;
	/** Loop through 1000 vriable names stored in macrovariable var_list **/
		%do j=2 %to 1000;
		/** add suffix _var to current variable and take the first element **/
			%scan(&amp;amp;var_list,&amp;amp;j.)_var {1}=%scan(&amp;amp;var_list,&amp;amp;j.);
		%end;
	%end;
	%else %if time2 = time %then %do;
		%do k=2 %to 1000;
		/** add suffix _var to current variable and take the second element **/
			%scan(&amp;amp;var_list,&amp;amp;k.)_var {2}=%scan(&amp;amp;var_list,&amp;amp;k.);
		%end;
	%end;
	%else %if time3 = time %then %do;
		%do n=1 %to 1000;
		/** add suffix _var to current variable and take the third element **/
			%scan(&amp;amp;var_list,&amp;amp;n.)_var {3}=%scan(&amp;amp;var_list,&amp;amp;n.);
		%end;

	%end;
%mend getArrayData;&lt;/PRE&gt;
&lt;P&gt;One simplification I can make is that in Dataset Old and Have1, time can only ever be 10,11 or 12.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;data Old;
  input ID time a;
datalines;
999 10 3
999 11  .
999 12 4
99  10 5
99  11 .
99  12 .
;&lt;BR /&gt;run;&lt;/PRE&gt;
&lt;PRE class="language-sas"&gt;&lt;CODE&gt;data have1;
  input ID a1-a3 time1-time3;
datalines;
 99 . . . 1 2 3
 99 . . . 10 11 12
999 . . . 1 2 3
999 . . . 10 11 12
;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 26 Oct 2022 04:51:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840747#M332426</guid>
      <dc:creator>nstdt</dc:creator>
      <dc:date>2022-10-26T04:51:24Z</dc:date>
    </item>
    <item>
      <title>Re: Changing from Long to Wide dataset involving array variables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840755#M332430</link>
      <description>&lt;P&gt;Maxim 19: Long Beats Wide.&lt;/P&gt;
&lt;P&gt;Transpose your have1 dataset to long, then it turns into a simple join on id and time. From then on, stay with the long dataset layout.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data long;
set have1;
array _a {*} a1-a3;
array _t{*} time1-time3;
do i = 1 to 3;
  time = _t{i};
  a = _a{i};
  output;
end;
keep id time a;
run;

proc sql;
create table want as
  select
    long.id,
    long.time,
    coalesce(long.a,old.a) as a
  from long left join old
  on long.id = old.id and long.time = old.time
;
quit;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 26 Oct 2022 07:04:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Changing-from-Long-to-Wide-dataset-involving-array-variables/m-p/840755#M332430</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2022-10-26T07:04:34Z</dc:date>
    </item>
  </channel>
</rss>

