BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
genemroz
Quartz | Level 8

I need help creating temporary arrays from a dataset.

 

Dataset psolib.cameras contains 22 records. To create a new dataset I need to have access to 6 unique values (1 character, 5 numeric) from each of the 22 records (6 x 22)=132 values in all. I'm trying to use the values in the temporary arrays for lookup and calculation purposes. Below is my code and the blood-red list of errors it generated. Any help would be greatly appreciated. 

 

Thanks to all who care to respond in advance....! 

 

Gene

 

 

1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
72
73 data _null_;
74 array station(22) _temporary_;
75 array xpos(22) _temporary_;
76 array ypos(22) _temporary_;
77 array xhat(22) _temporary_;
78 array yhat(22) _temporary_;
79 array zhat(22) _temporary_;
80 set psolib.cameras end=eof;
ERROR: Variable station has been defined as both character and numeric.
ERROR: The variable type of xpos is invalid in this context.
ERROR: The variable type of ypos is invalid in this context.
ERROR: The variable type of xhat is invalid in this context.
ERROR: The variable type of yhat is invalid in this context.
ERROR: The variable type of zhat is invalid in this context.
81 do i=1 to 22;
82 station(i)=station;
ERROR: Illegal reference to the array station.
83 xpos(i)=xpos;
ERROR: Illegal reference to the array xpos.
84 ypos(i)=ypos;
ERROR: Illegal reference to the array ypos.
85 xhat(i)=xhat;
ERROR: Illegal reference to the array xhat.
86 yhat(i)=yhat;
ERROR: Illegal reference to the array yhat.
87 zhat(i)=zhat;
ERROR: Illegal reference to the array zhat.
88 end;
89 run;

data _null_;
array station(22) _temporary_;
array xpos(22) _temporary_;
array ypos(22) _temporary_;
array xhat(22) _temporary_;
array yhat(22) _temporary_;
array zhat(22) _temporary_;
set psolib.cameras end=eof;
do i=1 to 22;
station(i)=station;
xpos(i)=xpos;
ypos(i)=ypos;
xhat(i)=xhat;
yhat(i)=yhat;
zhat(i)=zhat;
end; 
run;
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

You are trying to use the same name for the variable and the array.  Array names cannot be a name that is already being used for a variable.  Also if one of those arrays should hold character variables then you tell SAS that fact in the ARRAY statement.  If you have 5 numeric variables then why not just make one 2D array instead of five 1D arrays?

data test;
  array _station(22) $20 _temporary_;
  array xyz(5,22) _temporary_;
  if _n_=1 then do i=1 to min(22,nobs);
    set psolib.cameras nobs=nobs;
    _station(i)=station;
    xyz(1,i)=xpos;
    xyz(2,i)=ypos;
    xyz(3,i)=xhat;
    xyz(4,i)=yhat;
    xyz(5,i)=zhat;
  end;
  set have;
  ... do something with the arrays ...
run;

View solution in original post

4 REPLIES 4
Tom
Super User Tom
Super User

You are trying to use the same name for the variable and the array.  Array names cannot be a name that is already being used for a variable.  Also if one of those arrays should hold character variables then you tell SAS that fact in the ARRAY statement.  If you have 5 numeric variables then why not just make one 2D array instead of five 1D arrays?

data test;
  array _station(22) $20 _temporary_;
  array xyz(5,22) _temporary_;
  if _n_=1 then do i=1 to min(22,nobs);
    set psolib.cameras nobs=nobs;
    _station(i)=station;
    xyz(1,i)=xpos;
    xyz(2,i)=ypos;
    xyz(3,i)=xhat;
    xyz(4,i)=yhat;
    xyz(5,i)=zhat;
  end;
  set have;
  ... do something with the arrays ...
run;
genemroz
Quartz | Level 8

Tom and Ballard:

 

Thanks for the prompt reply.  I integrated Tom's suggested code into the procedure that I'm developing and ran a test case.  But I got an error message: Data step stopped due to looping.  The entire code is below.  Ultimate goal of code is dataset that looks like:

Tx   Ty  k..........extended to include a separate column of k values for each Station

-10 -10 ( 1 or 0).......

.

.

.

10 10  (1 or 0)..........

 

You've already helped a great deal and thanks for that.  I hope you can help me over this last hurdle.

 

Gene

 

data TIST7;
keep Tx Ty k;
/*Create Temporary Arrays*/
/*data _null_;*/
  array _station(22) $20 _temporary_;
  array xyz(5,22) _temporary_;
  if _n_=1 then do i=1 to nobs;
    set psolib.cameras nobs=nobs;
    _station(i)=station;
    xyz(1,i)=xpos;
    xyz(2,i)=ypos;
    xyz(3,i)=xhat;
    xyz(4,i)=yhat;
    xyz(5,i)=zhat;
  end;
/*Test of Camera location and vector data from temporary array*/
 /* 3D Unit Vector of Camera*/
xhat=xyz(3,1);
yhat=xyz(4,1);
zhat=xyz(5,1);
/*Camera Location*/
Cx=xyz(1,1);
Cy=xyz(2,1);
Cz=0;
/*Set parameters for Target grid dimensions*/
Txmin=-10; Txmax=10; nx=1;
Tymin=-10; Tymax=10; ny=1;
dx=(Txmax-Txmin)/(nx);
dy=(Tymax-Tymin)/(ny);
/*Start loop through Targets and initialize k-coverage*/
/*Creates separate grid for each camera--not exactly what I want but possibly useful*/
do Ty=Tymin to Tymax by dy;
do Tx=Txmin to Txmax by dx;
k=0; /*Initialize k-coverage to 0)*/
/*Create Target Vector from Camera to target (at 100km altitude) in 3D Cartesian grid*/
CTx=Tx-Cx;
CTy=Ty-Cy;
CTz=100-Cz;
/*Calculate distance from Camera to Target in 3 Dimensions*/
CTdist=sqrt(CTx**2+CTy**2+Ctz**2);
/*Calculate Angle between Unit Vector and Target Vector*/
SepAngle=arcos(((xhat*CTx)+(yhat*CTy)+(zhat*CTz))
/(sqrt(CTx**2 + CTy**2 + CTz**2)*sqrt(xhat**2 +yhat**2 + zhat**2)))*(180/constant('pi'));
/*Test Angle against FoV/2 and Test distance to target*/
if Sepangle LE 88/2 and CTdist<200 then k=1; /*Set k-coverage to 1 if Target within FoV*/
output;
end;
end;
run;

 

 

Tom
Super User Tom
Super User

Most data steps stop when they read past the end of the input dataset.  Your code does not really have an input dataset, just the one you are putting into the array.

 

So you can either add a STOP statement before the RUN statement. Or just remove the IF _N=1 THEN part of the code so that one the second iteration of the data step it will stop when it reads past the end of the dataset.

 

Note that your DO loop is going to cause trouble because of floating point rounding.  Instead of trying to use a non-integer BY value just increment by 1 over the number of iterations you want to do and then calculate the value based on what iteration you are on.

Txmin=-10; Txmax=10; nx=1;
dx=(Txmax-Txmin)/(nx);

do x_index=0 to nx ;
  tx = txmin + x_index * dx ;
...
ballardw
Super User

First Array names CANNOT be the same as the name of variable in a data set.

This is the cause of these errors:

83 xpos(i)=xpos;
ERROR: Illegal reference to the array xpos.

You could get around that by defining the arrays as something like:  xpos_  the under score to make a new name.

 

Second when you declare an array that you expect to hold character values you need to specify that in the definition and how long the values are expected to be.

 

Array char (5) $ 25 _temporary_;

This is likely the cause of the

ERROR: Variable station has been defined as both character and numeric.

as your array defines numeric and the data set has character.

 

Third, I think you need to share an example of your data and what you expect the result to look like.

 

Fourth, _temporary_ variables cease to exist at the end of data step code, so they would not be available for "look up" at a later step.

 

And last, you will have 22 identical values of each of the variables for duration of one step through the data. Which is why I say you need to show what you expect us to play with. An Example of 3 to 5 records from the psolib.cameras data set might work.

 

Here's an example of what I think you are, at least in part, wanting to use.

data example;
   input x $ y z ;
datalines;
abc  123  456
pdq  678  999
ghg  333  555
;

data temp;
   set example;
   array x_ (3) $ 8 _temporary_;
   array y_ (3) _temporary_;
   array z_ (3) _temporary_;
   x_[_n_] = x;
   y_[_n_] = y;
   z_[_n_] = z;
   put "Observation="_n_ X_[1]= X_[2]= X_[3]= ;
   put "Observation="_n_ Y_[1]= Y_[2]= Y_[3]= ;
   put "Observation="_n_ Z_[1]= Z_[2]= Z_[3]= ;
run;

Note that the _temporary_ variables are not in the data set.

_n_ is an automatic variable that indicates the number of times the data step iterates. In this simple case it indicates the row of data read from the data set on the set statement.

The "temporary" arrays are not filled until the last record is read.

I don't know what you expect to do with the result on the last record though.

 

So it may help to show how you expected to use the values placed in the arrays.

 

 

 

sas-innovate-wordmark-2025-midnight.png

Register Today!

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.


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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 2172 views
  • 0 likes
  • 3 in conversation