proc contents data = SASHELP.ELECTRIC order=varnum; run;
data Have;
set SASHELP.ELECTRIC(keep = Revenue Coal Hydro);
array var Revenue Coal Hydro;
array fmt DOLLAR10 COMMA10 COMMA10;
array new t_Revenue t_coal t_Hydro;
do over var;
new=put(var,fmt);
end;
run;
How do I pass a comma through to my fmt array?
OR
Is there an easier way to grab the formatted value lables and put into a new variable??
Thanks!!
The functions PUTN and PUTC allow you to use the value of a text variable as the format.
Also the Do Over array statement isn't reliable when addressing multiple arrays.
A temporary array is a better way to use a list of values. The way you declared the FMT array it was expecting variables named Dollar10 and Comma10 not the values. Note that the values for the format include the . in the text vale.
I think you may be looking for something like this:
data Have;
set SASHELP.ELECTRIC(keep = Revenue Coal Hydro);
array var Revenue Coal Hydro;
array fmt {3} $10 _temporary_ ( "DOLLAR10.", "COMMA10." ,"COMMA10." );
array new t_Revenue t_coal t_Hydro;
do i = 1 to dim(var);
new[i]=putn(var[i],fmt[i]);
end;
drop i;
run;
The functions PUTN and PUTC allow you to use the value of a text variable as the format.
Also the Do Over array statement isn't reliable when addressing multiple arrays.
A temporary array is a better way to use a list of values. The way you declared the FMT array it was expecting variables named Dollar10 and Comma10 not the values. Note that the values for the format include the . in the text vale.
I think you may be looking for something like this:
data Have;
set SASHELP.ELECTRIC(keep = Revenue Coal Hydro);
array var Revenue Coal Hydro;
array fmt {3} $10 _temporary_ ( "DOLLAR10.", "COMMA10." ,"COMMA10." );
array new t_Revenue t_coal t_Hydro;
do i = 1 to dim(var);
new[i]=putn(var[i],fmt[i]);
end;
drop i;
run;
can you tell me more about the dangers of multiple arrays in a do-over loop?
Thank you!
The first issue is it becomes very easy to generate an error of array out of bounds if all arrays are not of the same size.
data junk;
input x1 - x5 y1-y4;
array x x:;
array y y:;
do over x;
put x=;
put y=;
end;;
datalines;
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 10
;
run;
ANY use of the array y is going to have issues when you get to the fifth element of X in the above. And if you change it to use Y as the controller then the last element of X never gets processed. Yes the example is trivial but it demonstrates the principal.
Second is that when you need to conditionally reference an element. When using Do i = 1 to dim(x) you have the ability to check if the element you are processing in x is the such the first with "If i=1 then do" or last: "if i= dim(x) ".
Also any time when you may need to reference different elements of two arrays or mulitiple elements of the same array at the same time which may occur with ordering the elements of an array or finding the max,min, mean etc of groups of 3 or 4 elements is just not feasible.
Note that the DO OVER code is not even documented in SAS since version 8.
I would pretty much restrict the use of DO OVER to single operations on single arrays.
I shudder trying to use Do Over with a two dimensional array.
Thanks! That example makes the dangers clear.
I'll be using explicit array references from now on 😉
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.