BookmarkSubscribeRSS Feed
JasonNC
Quartz | Level 8

Hi,

I am having a problem with arrays when there are no records in the dataset

PROC SQL NOPRINT;

SELECT COUNT(*) INTO :CNT

FROM DETAILS;

QUIT;

DATA TEST;

SET PERSONS;

IF &CNT > 0 THEN DO;

ARRAY DTL {&CNT} $10. _TEMPORARY_;

DO i=1 to &CNT;

DTL{i}=DETAIL;

OUTPUT;

END;

END;

RUN;

I kept the condiiton to do it only in cases where the record count is > 0 but when i ran this program and there is no data it throws the error

ERROR: Invalid dimension specification for array DTL.  The upper bound of an array dimension is smaller than its corresponding

       lower bound.

Why it is generating this error even when i kept the condition &CNT > 0 .

5 REPLIES 5
Tom
Super User Tom
Super User

Array statements are not executable. They are just used to setup the data step.  So it is the same as if the ARRAY statement is outside of the IF/THEN block.  Same for other non-executable statements like KEEP/DROP/RENAME/ etc.

Your example program does not make any sense.  You are assigning values to temporary variables that will just be thrown away.

What do you actually want to do? Perhaps there is a better way to do it?

JasonNC
Quartz | Level 8

Hi Tom,

I am doing a cartesian join there.

For example i have a dataset like this Persons

Persons

John

Tom

Jim

Drug Tests

TB

BB

CF

i am creating a data set like this

John  TB

John BB

John CF

JIm TB

Jim BB

JIm CF

Reeza
Super User

Cross join in SQL instead?

proc sql;

create table want as

select p.*, t.*

from persons p

cross join

tests t;

quit;

Tom
Super User Tom
Super User

SQL is the easiest.

To do it with a data step you do not need any macro variables.

data want ;

  set persons;

  do i=1 to nobs;

     set drugtests nobs=nobs point=i;

     output;

  end;

run;


If you want to keep the people when there are no drug tests you can add.


if nobs=0 then output;


mkeintz
PROC Star

Tom has pointed out the erroneous assumptions your program embodies about the non-executable nature of the ARRAY statement, and even if the program ran to completion it wouldn't do anything.

But assuming the program did do some real work, (say you were looking for the 2nd largest value in a collection), you could still use &CNT as an upper bound if you used 0 as a lower bound, as in

  ARRAY DTL {0:&CNT} $10. _TEMPORARY_;

The array statement is still not executable, but if &CNT is zero, this statement would have avoided the implicit definition of an array with lower bound of 1 (the default) and upper bound of 0.  That's what provoked the "upper bound of an array is smaller than ..." message.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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