BookmarkSubscribeRSS Feed
tejeshwar
Calcite | Level 5
Hi,

I ran into a weird issue with Arrays this morning.
If I run this, it works perfectly fine. I dont want to define the number of elements in the array
ARRAY accttant {*} xs as is rs ds;

however it gives me the error while running this

ARRAY accttantt {*} 123 211 234;

ERROR: The array accttantt has been defined with zero elements.
ERROR 352-185: The length of numeric variables is 3-8.

ERROR 22-322: Syntax error, expecting one of the following: a name, (, ;, _ALL_, _CHARACTER_,
_CHAR_, _NUMERIC_, _TEMPORARY_.

ERROR 200-322: The symbol is not recognized and will be ignored.

Please help.

Regards,
Tejeshwar
8 REPLIES 8
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
SAS variable names must start with an alpha character. Also, consider using parentheses instead of brackets, unless you prefer the uniqueness of brackets when reading array-related code (strictly cosmetic - nothing more).


Scott Barry
SBBWorks, Inc.
tejeshwar
Calcite | Level 5
Hi,

I am trying to input values to the array, and not variable names.
For ex: If I define the number of elements in the array, the same syntax works perfectly.
For ex:
data d;
ARRAY accttanttt {3} (123 321 234);
run;

NOTE: Remote submit to SERVER commencing.
32 data d;
33 ARRAY accttanttt {3} (123 321 234);
34 run;

NOTE: The data set WORK.D has 1 observations and 3 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds

Here is the print of that dataset

Obs accttanttt1 accttanttt2 accttanttt3

1 123 321 234

I am confused as to why it doesnt works when we dont define the array elements.

Regards,
Tejeshwar
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
The two sceanarios you describe are very different, so why would you expect the behavior to be consistent (round hole, square peg)?

Reading the DOC, you need to declare some array content attribute - here is one approach to consider:


%let x_vals = 1 2 3 4 5;
* incoming array data values known, now use them in the DATA step. ;
data x;
array x ( %sysfunc(countw(&x_vals)) ) _temporary_ (&x_vals);
do i=1 to dim(x);
putlog x(i)= ;
end;
run;


Scott Barry
SBBWorks, Inc.
tejeshwar
Calcite | Level 5
Thanks Scott.
This worked the way I want it to work. I have one more question that I am troubling you with. My actual data values are of length 16, however while producing the output SAS displays it like 6.7392E15
I tried to define the length while defining the array, but it throws me an error

ERROR 352-185: The length of numeric variables is 3-8.

Will there be a way around this?

Regards,
Tejeshwar
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
The SAS LENGTH and FORMAT attributes are quite different.

Scott Barry
SBBWorks, Inc.

SAS 9.2 Language Ref: Dictionary, Formats
http://support.sas.com/documentation/cdl/en/lrdict/61724/HTML/default/a000309859.htm

SAS 9.2 Language Concepts - SAS Variables
http://support.sas.com/documentation/cdl/en/lrcon/61722/HTML/default/a000998827.htm
tejeshwar
Calcite | Level 5
Thanks Scott.
I used the below to generate what i needed, the format is also resolved now

data x;
array ab ( %sysfunc(countw(&acct)) ) (&acct);
do i=1 to dim(ab);
format _ALL_ 16.;
end;
run;
Cynthia_sas
SAS Super FREQ
Hi:
If all you wanted to do was FORMAT the numbers, you did not need an array at all. You could have used
[pre]
format _ALL_ 16.;
OR
format _NUMERIC_ 16.;
[/pre]

in your DATA step program, without any ARRAY processing.

Certain statements in SAS are considered "compile time statements", as described here in the doc:
http://support.sas.com/documentation/cdl/en/lrdict/61724/HTML/default/a001225397.htm

The documentation makes the distinction between "executable" statements and "declarative" statements, but also says that "declarative" statements "take effect when the system compiles program statements"

This paper is a good introduction to how the DATA step operates:
http://www2.sas.com/proceedings/sugi29/252-29.pdf

And this is specific documentation on the FORMAT statement:
http://support.sas.com/documentation/cdl/en/lrdict/61724/HTML/default/a000178212.htm

So, the FORMAT statement only gets used at compile time. Therefore, your do loop was not required, if all you wanted to do was apply the format to _ALL_ the variables (assuming that all the variables were numeric). Additionally, you could have used _NUMERIC_ to apply the 16. format to all the numeric variables in the data set.

You can test out the behavior of the FORMAT statement WITHOUT a do loop by running the program below. It shows both _ALL_ and _NUMERIC_. And, of course, the best place to set the format for your variables is when you are reading them into SAS data set format, if possible. I could have put the FORMAT statement in the program with the INFILE/INPUT statements. That way, I would ensure that my desired formats (and/or labels) were already in place the first time I went to use the data set.

cynthia
[pre]
data testfmt;
infile datalines;
input x y z;
return;
datalines;
6712345678901234 7821346573704321 5532652376996357
;
run;

proc print data=testfmt;
title 'proc print with no formats';
run;

** set format WITHOUT array (assumes all variables are numeric);
data withfmt;
set testfmt;
format _all_ 16.;
run;

proc print data=withfmt;
title 'New Data Set With Formats';
run;

proc contents data=withfmt;
title 'What is in Descriptor Portion of Data Set?';
run;

** what if data set has both character and numeric vars;
data withchar;
set testfmt;
longword = 'supercalifragilisticexpealidocious';
format _numeric_ 16. _character_ $34.
run;

proc print data=withchar;
title 'New Data Set With Character Variable';
run;

proc contents data=withchar;
title 'What is in Descriptor Portion of Data Set?';
run;

[/pre]
tejeshwar
Calcite | Level 5
Hi Cynthia,

Thanks for a detailed reply, was extremely helpful.
I know it just looks from the code that I pasted that all I am doing is trying to format the variable, however there is a lot more to it 🙂

My broader objective was to build a dynamic code and more importantly dynamic array. The only place I was stuck was that I have used arrays to take values from different variables, but I wanted to build an array which can take different values of single variable. I had used a Proc Select into: statement to have the values depicted into a single macro variable &acct. and then Scott helped me in using that to build a dynamic array.

Once the above was done, I noticed that my input values were of 16byte however the actual output showed me a value like 60493E45. and hence I just added "FORMAT _ALL_ 16. to the loop, and havent actually pasted the rest of it.

But thanks for sending a detailed information, it really helps a lot, since I am also relatively new to SAS.

Regards,
Tejeshwar

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
  • 4867 views
  • 0 likes
  • 3 in conversation