In a code snippet not shown here I use the coalesce(c) functions in an array context.
But I want the coalesce function to start from the last element of the array.
I've found a workaround for my code but I wonder if I can invert the order of an array.
For sure I could use 'do dim(array) to 1...' but this doesn't work for 'of array[*]' usage.
So in my basic example I want to array _var to have weight as the first element without changing the order for which it was defined.
data class;
set sashelp.class;
run;
data class2;
set class;
array _var (3) Age Height Weight;
array _retain (3) _Age _Height _Weight;
array _mult (3) (1 2 3);
do i=1 to dim (_var);
_retain(i)=_var(i)*_mult(i);
end;
run;
array temp1 (4) type_files1 type_files2 type_files3 type_files4;
lastnonmiss1=whichc(coalescec(of temp1[*]), of temp1[*]);
Reverse an array like this, then you can do anything you want with it.
data a;
array temp temp1-temp4;
array reverse(4) _temporary_;
temp1=1;
temp2=2;
temp3=.;
temp4=.;
do i=1 to dim(temp);
reverse(i)=temp(dim(temp)-i+1);
end;
calc = coalesce(of reverse{*});
drop i;
run;
Hi,
loop from last to first and compare manually:
do i=dim(temp1) to 1;
if vvalue(temp1[i]) eq coalescec(of temp1[*]) then lastnonmiss1=i;
end;
- Cheers -
@Oligolas wrote:
Hi,
loop from last to first and compare manually:
do i=dim(temp1) to 1; if vvalue(temp1[i]) eq coalescec(of temp1[*]) then lastnonmiss1=i; end;
UNTESTED but shouldn't that say
do i=dim(temp1) to 1 by -1;
?
of course, it's by -1
My mistake
- Cheers -
Thanks, nice trick but it doesn't solve my challenge.
The array elements were constructed from left to right if available meaning that if my array dimension is 4 then the elements could be
temp1(1)=csv
temp1(2)=xlsx
temp1(3)=''
temp1(4)=''
Your code still resolves to 1 (or 4 in your inverse order) as the condition becomes true for the coalescec result that in my understanding is still the first array element.
Reverse an array like this, then you can do anything you want with it.
data a;
array temp temp1-temp4;
array reverse(4) _temporary_;
temp1=1;
temp2=2;
temp3=.;
temp4=.;
do i=1 to dim(temp);
reverse(i)=temp(dim(temp)-i+1);
end;
calc = coalesce(of reverse{*});
drop i;
run;
With FCMP you can write your own COALESCECR function, however due to limitations of FCMP the implementation would accept only a character array (not an OF var(*) argument which expands to a variable number of individual arguments), OR a fixed number of arguments (not useful)
options cmplib='';
proc fcmp outlib=sasuser.sandbox.udf;
function coalescecR(s(*) $) $ 200;
do index = dim(s) to 1 by -1;
if not missing(s[index]) then return (s[index]);
end;
return ('');
endsub;
quit;
options cmplib=sasuser.sandbox;
data want; set have; array s a b c d e f g; lastc = coalescecR(s); /* <------------------- */ put lastc=; run;
For numbered range lists (as in your second example) you can reverse the order without an array:
data have; array tf[4] $ ('csv' 'xlsx' ' ' ' '); run; data want; set have; lastnonmiss=whichc(coalescec(of tf4-tf1), of tf1-tf4); run;
These reversed ranges can also be used in an array definition:
data want;
set sashelp.pricedata;
array revprice[*] price17-price1;
/* ... */
run;
(so that revprice[1] equals price17, revprice[2] equals price16, etc.).
data class; set sashelp.class; run; proc sql noprint; select name into :vnames separated by ' ' from dictionary.columns where libname='WORK' and upcase(name) in ('AGE' 'WEIGHT' 'HEIGHT') order by varnum desc; quit; %put &=vnames. ;
Why not just list the elements in the opposite order?
The code you posted that is using the array to perform calculations does not depend on the order that the variables are listed in the array definition.
And if you have a simple list of variables with a numeric suffix then you can make a variable list from last to first as easily as from first to last.
Also there is no need to define an array to use the coalescec() function.
lastnonmiss1=coalescec(of type_files4-type_files1);
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.