BookmarkSubscribeRSS Feed
AvocadoRivalry
Calcite | Level 5

I have the following arrays I need defined, which worked fine with the original code:

array T Ts1-Ts50;

array Q Qs1-Qs50;

 
Due to some code changes, there will not always be 50 values and the number of observations is being defined as a macro variable earlier in the program.  I'm not sure if this is something specific to arrays or I'm just doing something silly when trying to call the macro variable in the name for the arrays, but hopefully this is a quick fix.  Here is the full set of code that tries to reference the macro variable to replace the Ts50 or Qs50 with the number needed:


data Default;
set Default;
if _N_ eq 1 then do; set Ts; set Quants; end;

array T Ts1-Ts&bins_needed.;
array Q Qs1-Qs&bins_needed.;

if quick_ratio lt Qs1 then T_QUICK = Ts1;
else if quick_ratio ge Qs&bins_needed. then T_QUICK = Ts&bins_needed.;
else do;
do i = 1 to (&bins_needed. - 1);
  if quick_ratio ge Q and quick_ratio lt Q[i+1] then T_QUICK = T;
end;
end;

%end;

drop Ts1-Ts&bins_needed. Qs1-Qs&bins_needed. i;
run;

8 REPLIES 8
art297
Opal | Level 21

You didn't provide any example data, or desired result based on that data, thus one can only guess.  Hopefully, the following is at least close to what you want to accomplish:

*Build some test data;

data ts (drop=i);

  array ts(3);

  do i=1 to 3;

    ts(i)=i;

  end;

run;

data Quants (drop=i);

  array qs(3);

  do i=1 to 3;

    qs(i)=i;

  end;

run;

data Default;

  input quick_ratio;

  cards;

.5

1

3

.8

2

;

data Default;

  set Default;

  if _N_ eq 1 then do;

    set Ts;

    set Quants;

    array _T(*) Ts:;

    array _Q(*) Qs:;

    retain _T: _Q:;

  end;

  if quick_ratio lt _Q(1) then T_QUICK = _T(1);

  else if quick_ratio ge _Q(dim(_Q)) then T_QUICK = _T(dim(_Q));

  else do;

    do i = 1 to dim(_Q)-1;

      if quick_ratio ge _Q and quick_ratio lt _Q[i+1]

       then T_QUICK = _T;

    end;

  end;

  drop ts: Qs: i;

run;

FriedEgg
SAS Employee

I'm not sure I understand what you are asking.  I do some minor cleanup and remove an erronious %end;

Are you wanting to determine the value of bins_needed or explicitly define it, like I have here?

The proper syntax for an array statement is available here: http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000201956.htm

%let bins_needed=15;

data default;

set default;

if _N_ eq 1 then

  do;

   set Ts;

   set Quants;

  end;

array T

  • Ts1-Ts&bins_needed;
  • array Q

  • Qs1-Qs&bins_needed;
  • if quick_ratio lt qs[1] then

      T_QUICK = ts[1];

    else if quick_ratio ge Qs&bins_needed then

      T_QUICK = ts[&bins_needed];

    else

       do i = 1 to (&bins_needed - 1);

        if quick_ratio ge Q and quick_ratio lt Q[i+1] then T_QUICK = T;

       end;

    drop Ts1-Ts&bins_needed Qs1-Qs&bins_needed i;

    run;

    Tom
    Super User Tom
    Super User

    I am sorry, but what is the question?  Did you get an error message? Or are you not getting the expected results?

    Tom
    Super User Tom
    Super User

    Looks like you are just trying to generate T_QUICK based on which bin QUICK_RATIO falls into.

    Does not look like you even need to know how many bins there are to do that.

    Take a look at this example. Play with the condition in the UNTIL() clause to get it to pick the right bin.

    data v_quants;

      input ratio @@;

    cards;

    0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

    run;

    proc transpose out=quants(drop=_:) prefix=Qs;

    run;

    data Default;

      input quick_ratio @@;

      if _N_ eq 1 then set Quants;

      array qs qs: ;

      do i=1 to dim(qs) until (quick_ratio < qs(i) );

        t_quick = qs(i);

      end;

      drop qs: i ;

    cards;

    0.05 0.15 0.2 1.0 1.5

    run;

    proc print;

    run;

           quick_

    Obs     ratio    t_quick

    1      0.05       0.1

    2      0.15       0.2

    3      0.20       0.3

    4      1.00       1.0

    5      1.50       1.0


    shinnen1
    Calcite | Level 5

    If you want to dynamically set the number of items in an array you can call a macro variable as follows in the array statement.

    %let periods    = 99;

      data xxxx.....

        array personnel_expense     {*} personnel_expense1     - personnel_expense%eval(&periods);

      run;

    AvocadoRivalry
    Calcite | Level 5

    Thanks Shinnen1 - that was exactly what I was looking for.  I wanted to change the original code as little as possible, as it was not written by me, so the %eval function is exactly what I needed.  The problem I was having was creating a flexible value to define the last element in the array each time the macro runs and that syntax seems to work exactly as I need it to.    

    Tom
    Super User Tom
    Super User

    If that fixes your problem then most likely the underlying cause is that the macro variable has spaces in it.

    I usually use this simple code to fix that.

    %let bins_needed=&bins_needed;

    I find this usually happens when using PROC SQL to generate a count.

    proc sql noprint ;

       select count(*) into :count from sashelp.class;

    quit;

    %put count="&count";

    %let count=&count;

    %put count="&count";

    395  %put count="&count";

    count="      19"

    396  %let count=&count;

    397  %put count="&count";

    count="19"

    AvocadoRivalry
    Calcite | Level 5

    That could have been it.  I did use PROC SQL to generate the bins_needed variable.  

    sas-innovate-2024.png

    Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

    Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

     

    Register now!

    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.

    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
    • 8 replies
    • 1003 views
    • 0 likes
    • 5 in conversation