BookmarkSubscribeRSS Feed
Sascoder
Obsidian | Level 7

I need to create a string of numbers in a very specific way and calling a function where I pass different parameter values seems the easiest way.  I discovered proc fcmp and got it mostly working except that it only works with temporary arrays and I can't figure out a work-around. 

 

Data would be like

obs1 101 001 001

obs2 010 100 101

obs3 100 010  010

 

And here is an example of what I might want as output. I want to be able to manipulate each cluster of numbers differently.

obs1 10 001 01

obs2 01 100 01

obs3 10 010 10

 

The data is stored in variables that match a 2 dimensional array. And the actual number of values per cluster varies.  My idea to accomplish this is to nest user-defined functions within the cats function.  But I need a way to pass the numbers to the function in a practical way.

 

In this function colim, det is the array.  If I create a temporary array (dys) from the main data, this works, but that doesn't accomplish what I want to do.  Passing just the variables doesn't work, and passing values as part of a permanent array doesn't work (not sure my syntax is right here).

 

I thought about creating another function (or macro) to create the temporary array but I am not sure how to make that work.  It still has the temporary array problem.

 

*In this example, det is the array;

proc fcmp trace flow outlib=sasuser.userfuncs.ex;
FUNCTION colim(syr , eyr , cdet $, det[*]) $ 12;
length histi $12;
tot = 0;
if eyr = 0 then histi=' ';
else do i=syr to (eyr - 1);
     tot = tot + det[i]; 
   end;
   if tot ge 1 then col = '1';
   histi= cats(col, cdet);

   return(histi);
endsub;

*if I set up a temporary array-dys, - this works, but I need to be able to 
pull different subsets from tdays in the same concatenation; data tmp2; set tmp1; array tdays {11,10} yr06d1 - yr06d10 yr07d1 - yr07d10 yr08d1 - yr08d10
yr09d1-yr09d10 yr10d1-yr10d10 yr11d1-yr11d10 yr12d1-yr12d10
yr13d1-yr13d10 yr14d1-yr14d10 yr15d1-yr15d10 yr16d1-yr16d10; array dys(10) _temporary_; do i=1 to 10; dys(i) = tdays(2,i); end; *this works but doesn't accomplish what I need;
w = cats(colim('abc', 1, 6, yr07d6, dys), colim('abc', 2, 6, yr07d1, dys), 'x' ); **these don't work;
w = cats(colim('abc', 1, 6, yr06d6, yr06d1 - yr06d10), colim('abc', 3, 8, yr07d1, yr07d1 - yr07d10), 'x' ); w = cats(colim('abc', 1, 6, yr06d6, tdays[*]yr06), colim('abc', 3, 8, tdays[*]yr07), 'x' );
run;

I am using SAS 9.4.

 

Any help would be much appreciated!

 

4 REPLIES 4
ChrisNZ
Tourmaline | Level 20

Always reduce your problems to the simplest form and then search.

This works:

proc fcmp trace flow outlib=WORK.USERFUNCS.EX;
  function sumarray(ARR[*]) ;
    do I = 1 to dim(ARR);
       TOT = sum(TOT, ARR[I]); 
     end;
    return(TOT);
  endsub;
run;

options cmplib=WORK.USERFUNCS; 

data _null_;
  array DYS[3] _temporary_ (1 2 3);        
  W = sumarray(DYS);
  putlog W=; 
run;

W=6

 

 

Sascoder
Obsidian | Level 7

Thanks for the reply.

This solution doesn't generate the 01 strings.  It gives a sum.

I need to generate 01 strings from source 01 strings based on varied and situation specific conditions. 

 

Thanks again!

ChrisNZ
Tourmaline | Level 20
Adapt it. I pass an array and process it.You can do the same.
ChrisNZ
Tourmaline | Level 20

I added several dimensions to be closer to you need. Does this help you more?

proc fcmp trace flow outlib=WORK.USERFUNCS.EX;
  function sumarray(ARR[*,*],ROW) ;
    do I = 1 to 3;
      TOT = sum(TOT, ARR[ROW,I]); 
    end;
    return(TOT);
  endsub;
run;

options cmplib=WORK.USERFUNCS; 

data _null_;
  array DYS[2,3] (1 2 3 4 5 6);        
  W = sumarray(DYS,2);
  putlog W=; 
run;

W=15

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 762 views
  • 1 like
  • 2 in conversation