BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
chrissowden
Obsidian | Level 7

data tbl;

retain ord subord label _1 _2 _3 _9;

merge shell_final combo;

by subord;

if subord not in (1,4,5)then do;

if not missing(_1) then col1=put(_1, 3.)||' ('||put((_1/&tot1)*100,3.)||'%)';

else if missing(_1) then col1=put(0,3.);

if not missing(_2) then col2=put(_2, 3.)||' ('||put((_2/&tot2)*100,3.)||'%)';

else if missing(_2) then col2=put(0,3.);

if not missing(_3) then col3=put(_3, 3.)||' ('||put((_3/&tot3)*100,3.)||'%)';

else if missing(_3) then col3=put(0,3.);

if not missing(_9) then col9=put(_9, 3.)||' ('||put((_9/&tot9)*100,3.)||'%)';

else if missing(_9) then col9=put(0,3.);

 

 

end;

drop _1 _2 _3 _9;

run;

 

 

data tbl2;

retain ord subord label _1 _2 _3 _9;

merge shell_final combo;

by subord;

 

 

 

array vars{4} $ _1 _2 _3 _9;

do i=1 to 4;

if vars{i} ^=' ' and label='No' then vars{i}=put(vars{i}, 3.)||' ('||put((vars{i}/&tot9)*100,3.)||'%)';

end;

run;

 

 

I am trying to see if there is a way that I can replicate the first code into an array. tbl works for what I am doing but was wondering if I could use an array to accomplish the same thing. In the second code cluster is my attempt to trying an array, but it doesn't work.

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

First issue to clear up ... does the top program work properly?  If so, that establishes that _1 _2 _3 and _9 are numeric variables.  They don't belong in an array of character variables.

 

The character elements you are creating require 10 characters.  If you specify $ only, and not a length, you will assign a length of 8 which is not long enough.  Here's an array approach.  Note that it takes 3 arrays:

 

data want;

retain ord subord label;

merge shell_final combo;

array orig {4} _1 _2 _3 _9;

array denoms {4} _temporary_ (&tot1 &tot2 &tot3 &tot9);

array newvars {4} $ 10 col1 col2 col3 col9;

do k=1 to 4;

   if not missing orig{k} then newvars{k} =

   put(orig{k}, 3.) || ' (' || put((orig{k} / denoms{k}) * 100, 3.) || '%)';

   else newvars{k} = '  0';

end;

drop k _1 _2 _3 _9;

run;

 

The code is untested (that part is up to you), but looks about right.

 

View solution in original post

5 REPLIES 5
PeterClemmensen
Tourmaline | Level 20

This kind of problem is much easier to help you with if you provide some example data for testing your code. That means you will get your answer far quicker also.

chrissowden
Obsidian | Level 7

It's a big practice dataset from work. it was just an idea that I was thinking about.

ballardw
Super User

@chrissowden wrote:

It's a big practice dataset from work. it was just an idea that I was thinking about.


So provide a small subset of data, 5 to 10 records, and maybe a smaller number of variables. If an array will work with 4 variables it is very likely that it will scale to 40 or 400 variables.

 

And don't hide details with undefined macro variables such as your &tot1 &tot2 &tot3 &tot9

And then what the desired output should look like in some form.

 

Doesn't work is awful vague.

Are there errors in the log?: Post the code and log in a code box opened with the {i} to maintain formatting of error messages.

No output? Post any log in a code box.

Unexpected output? Provide input data in the form of data step code pasted into a code box, the actual results and the expected results. Instructions here: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... will show how to turn an existing SAS data set into data step code that can be pasted into a forum code box using the {i} icon or attached as text to show exactly what you have and that we can test code against.

Astounding
PROC Star

First issue to clear up ... does the top program work properly?  If so, that establishes that _1 _2 _3 and _9 are numeric variables.  They don't belong in an array of character variables.

 

The character elements you are creating require 10 characters.  If you specify $ only, and not a length, you will assign a length of 8 which is not long enough.  Here's an array approach.  Note that it takes 3 arrays:

 

data want;

retain ord subord label;

merge shell_final combo;

array orig {4} _1 _2 _3 _9;

array denoms {4} _temporary_ (&tot1 &tot2 &tot3 &tot9);

array newvars {4} $ 10 col1 col2 col3 col9;

do k=1 to 4;

   if not missing orig{k} then newvars{k} =

   put(orig{k}, 3.) || ' (' || put((orig{k} / denoms{k}) * 100, 3.) || '%)';

   else newvars{k} = '  0';

end;

drop k _1 _2 _3 _9;

run;

 

The code is untested (that part is up to you), but looks about right.

 

chrissowden
Obsidian | Level 7
Thanks so much. I had to make some changes to your code, but I got it to work. Thanks a bunch!

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 1115 views
  • 0 likes
  • 4 in conversation