<?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: Long to wide Ronein in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979776#M378850</link>
    <description>&lt;P&gt;This still requires multiple steps, but here is another idea.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
input offerID degem amnt;
cards;
111123 200 1000 
111123 300 2000
111123 400 3000
;
run;

data have;
set have ;
by offerid;
if first.offerid then count=0;
count+1;
run;

proc transpose data=have out=wide;
by count offerid;
var degem amnt;
run;

data wide;
set wide;
varname=catx('_',_name_,count);
run;

proc transpose data=wide out=wide1(drop=_name_);
by offerid;
id varname;
var col1;
run;

proc print;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Mon, 01 Dec 2025 12:48:18 GMT</pubDate>
    <dc:creator>Kathryn_SAS</dc:creator>
    <dc:date>2025-12-01T12:48:18Z</dc:date>
    <item>
      <title>Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979770#M378846</link>
      <description>&lt;P&gt;Hello&lt;/P&gt;
&lt;P&gt;In real life I have a big data set 17 million rows and many offer_ID's.&lt;/P&gt;
&lt;P&gt;Is there a better way to perform convertion from long to wide .&lt;/P&gt;
&lt;P&gt;Please see the current code&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;
data have;
input offerID degem amnt;
cards;
111123 200 1000 
111123 300 2000
111123 400 3000
;
run;
PROC TRANSPOSE DATA=have OUT=wide1(DROP=_name_) prefix=degem_;
BY offerID; 
VAR degem;
RUN;
PROC TRANSPOSE DATA=have OUT=wide2(DROP=_name_) prefix=Amnt_;
BY offerID; 
VAR degem;
RUN;
Data want_Wide;
merge wide1 wide2;
BY offerID; 
Run;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 01 Dec 2025 11:48:50 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979770#M378846</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2025-12-01T11:48:50Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979773#M378847</link>
      <description>&lt;P&gt;IMHO&lt;/P&gt;
&lt;P&gt;The best thing to do with this data set is to leave it as a long data set, and perform any analyses on the long data set. But you probably knew that already. The less processing you have to do on 17 million records, the better off you will be.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Please explain why you want it to be a wide data set.&lt;/P&gt;</description>
      <pubDate>Mon, 01 Dec 2025 14:50:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979773#M378847</guid>
      <dc:creator>PaigeMiller</dc:creator>
      <dc:date>2025-12-01T14:50:33Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979776#M378850</link>
      <description>&lt;P&gt;This still requires multiple steps, but here is another idea.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
input offerID degem amnt;
cards;
111123 200 1000 
111123 300 2000
111123 400 3000
;
run;

data have;
set have ;
by offerid;
if first.offerid then count=0;
count+1;
run;

proc transpose data=have out=wide;
by count offerid;
var degem amnt;
run;

data wide;
set wide;
varname=catx('_',_name_,count);
run;

proc transpose data=wide out=wide1(drop=_name_);
by offerid;
id varname;
var col1;
run;

proc print;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 01 Dec 2025 12:48:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979776#M378850</guid>
      <dc:creator>Kathryn_SAS</dc:creator>
      <dc:date>2025-12-01T12:48:18Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979781#M378851</link>
      <description>&lt;P&gt;Proc transpose has features that allow you to skip the step where you create VARNAME.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc transpose data=wide out=wide1(drop=_name_) delim=_;
   by offerid;
   *id varname;
   id _name_ count;
   var col1;
   run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 01 Dec 2025 14:37:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979781#M378851</guid>
      <dc:creator>data_null__</dc:creator>
      <dc:date>2025-12-01T14:37:06Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979784#M378852</link>
      <description>At my work have task to create a panel data which has one row ( wide structure) instead of long structure ( multiple rows per offer id).  I know it is strange but for most of people it is easier to look at wide structure data where each offer id has one row</description>
      <pubDate>Mon, 01 Dec 2025 14:59:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979784#M378852</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2025-12-01T14:59:36Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979798#M378854</link>
      <description>&lt;P&gt;And what analysis will you be doing?&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;When I look at the examples in &lt;A href="https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.4/etsug/etsug_panel_toc.htm" target="_self"&gt;PROC PANEL&lt;/A&gt; they are all long data sets, not wide data sets. Most SAS data analysis PROCs are designed to use long data sets.&lt;/P&gt;</description>
      <pubDate>Mon, 01 Dec 2025 17:28:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979798#M378854</guid>
      <dc:creator>PaigeMiller</dc:creator>
      <dc:date>2025-12-01T17:28:24Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979801#M378855</link>
      <description>&lt;P&gt;If you know the maximum number of DEGEMs or AMTs per OFFERID then it is simple using ARRAYs.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input offerID degem amnt;
cards;
111123 200 1000 
111123 300 2000
111123 400 3000
;

data want;
  set have;
  array _degem degem1-degem3 ;
  array _amnt amnt1-amnt3;
  do _n_=1 by 1 until(last.offerid);
    set have;
    by offerid;
    _degem[_n_]=degem;
    _amnt[_n_]=amnt;
  end;
  drop degem amnt;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;If you don't know the number you have two choices.&amp;nbsp; Just pick something that you know is too large.&lt;/P&gt;
&lt;P&gt;Or calculate it.&amp;nbsp; For example you could use PROC SQL to create a macro variable.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql noprint;
select max(count) into :max_count trimmed
from (select offerid,count(*) as count 
       from have group by offerid)
;
quit;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then use that macro variable to generate the arrays' upper bounds.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  array _degem degem1-degem&amp;amp;max_count ;
  array _amnt amnt1-amnt&amp;amp;max_count ;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 01 Dec 2025 17:49:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979801#M378855</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2025-12-01T17:49:20Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979821#M378857</link>
      <description>&lt;P&gt;If people need to&amp;nbsp;&lt;U&gt;look&lt;/U&gt; at it, it's a report, not a dataset. Hand them the PROC REPORT code so they can run it on the intended subset (nobody will manually inspect 17 million observations in a single lifetime).&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 01 Dec 2025 20:20:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979821#M378857</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2025-12-01T20:20:26Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979822#M378858</link>
      <description>&lt;P&gt;And another thing: if there's just one ID with lots of observations, the resulting dataset will be enormous and consist mainly of missing values.&lt;/P&gt;</description>
      <pubDate>Mon, 01 Dec 2025 20:23:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979822#M378858</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2025-12-01T20:23:23Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979835#M378862</link>
      <description>&lt;P&gt;1)The most simple way is using PROC SUMMARY, but the limited thing is the max number of row in each 'offerID' group is 100 .&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;
data have;
input offerID degem amnt;
cards;
111123 200 1000 
111123 300 2000
111123 400 3000
;
run;

proc sql noprint;
select max(n) into :n
 from (select count(*) as n from have group by offerID);
quit;

proc summary data=have;
by offerID;
output out=want(drop=_freq_ _type_) idgroup(out[&amp;amp;n.]  (degem amnt)=);
run;&lt;/CODE&gt;&lt;/PRE&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;2)My favorite way is using MERGE skill , but that need you to familiar with sas programming.&lt;/P&gt;
&lt;PRE&gt;data have;
input offerID degem amnt;
cards;
111123 200 1000 
111123 300 2000
111123 400 3000
;
run;

data temp;
 set have;
 by offerID;
 if first.offerID then n=0;
 n+1;
run;

proc sql;
create table level as
select distinct n from temp;
quit;

data _null_;
 set level end=last;
 if _n_=1 then call execute('data want;merge ');
 call execute(catt('temp(where=(n=',n,') rename=(degem=degem_',n,' amnt=amnt_',n,'))'));
 if last then call execute(';by offerID; drop n; run;');
run;&lt;/PRE&gt;</description>
      <pubDate>Tue, 02 Dec 2025 07:27:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979835#M378862</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2025-12-02T07:27:04Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979976#M378877</link>
      <description>&lt;P&gt;If the purpose is to look for commonality between the variables you might try a report such as this:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;Proc tabulate data=have;
   class offerid degem amnt;
   table offerid,
           degem amnt
          /misstxt=' '
   ;
   keylabel n=' ';
run;&lt;/PRE&gt;
&lt;P&gt;This will have one row for each offerid. The columns for degem and amnt will have the count of the number of times each value appears for that offerid and a blank space where there are none (the option MISSTEXT does the blank). The keylabel supresses the N that would otherwise appear in each column for the statistic.&lt;/P&gt;
&lt;P&gt;If you don't want a count but just an indicator then a custom format to display all the values 1 or greater as a single character could be created and used.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Note: this doesn't care what variable type any of the three variables are.&lt;/P&gt;</description>
      <pubDate>Wed, 03 Dec 2025 22:44:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/979976#M378877</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2025-12-03T22:44:01Z</dc:date>
    </item>
    <item>
      <title>Re: Long to wide Ronein</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/980426#M378937</link>
      <description>&lt;P&gt;I took a different approach, using the Lua procedure.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The initial step using SQL tells us how wide we need the table to be. We then use that information to generate the blank Got table with the required columns. Finally we parse the Have table into the Got table. In this example, we excluded blank records as a demonstration. I find this type of control structure to be much simpler in Lua than in base SAS.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;data have;
input offerID degem amnt;
cards;
111123 200 1000 
111123 300 2000
111123 400 3000
111124 500 4000
111124 . .
111124 550 4500
11125 600 5000
;
run;

proc sql;
	select max(numRecs) into :width
	from
	(select offerID, count(*) as numRecs
		from
		have
		group by offerID
	)
	;
quit;

proc lua;
	submit;
	local have = sas.open("have")
	local width = tonumber(sas.symget("width"))
	
	local want_vars = { {name = "offerID", type="N"} }
	
	for idx=1,width do
		table.insert(want_vars, {name = string.format("degem_%i",idx), type = "N"})
	end
	
	for idx=1,width do
		table.insert(want_vars, {name = string.format("Amnt_%i",idx), type = "N"})
	end
	
	sas.new_table("got", want_vars)
	local got = sas.open("got", "u")
	
	local curr_id
	local idx = 0
	for row in have:rows() do
		if row.offerid ~= curr_id then
			if curr_id then
				got:update()
			end
			got:append()
			curr_id = row.offerid
			got:put_value("offerID", curr_id)
			idx = 0		
		end
		if sas.missing(row.degem) == 0 or sas.missing(row.amnt) == 0 then
			idx = idx + 1
			got:put_value(string.format("degem_%i",idx), row.degem)
			got:put_value(string.format("Amnt_%i",idx), row.amnt)
		end
	end
	got:update()
	have:close()
	got:close()
	endsubmit;
run;&lt;/PRE&gt;</description>
      <pubDate>Tue, 09 Dec 2025 03:23:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Long-to-wide-Ronein/m-p/980426#M378937</guid>
      <dc:creator>qingy</dc:creator>
      <dc:date>2025-12-09T03:23:45Z</dc:date>
    </item>
  </channel>
</rss>

