This happens even when I apply STRIP to the character variable MAKE.
You reference members of an array with an integer index into the array. Not with a NAME. If you want to reference a variable by name then just reference the variable, there is no need to use an array.
If you need to convert a character variable with the name of a variable into the value of the variable the most direct way is to use the VVALUEX() function, but that would return the value as a character string. If you wanted the value converted back to a number then use INPUT() function.
length vw audi 8 make $32 ;
array brand vw audi (50.5 25.4);
model = 'VW';
mpg = input(vvaluex(model),32.);
Or you could find a method to convert the name to the index to use with the array. For example using the WHICHC() function might work.
model = 'VW';
mpg = brand(whichc(model,'VW','AUDI'));
Try this example:
data _null_;
length vw audi 8 make $32 ;
array brand vw audi (50.5 25.4);
input make ;
mpg1 = input(vvaluex(make),32.);
mpg2 = brand(whichc(make,'VW','AUDI'));
put (_all_) (=);
cards;
VW
AUDI
;;;;
Indices for arrays must be numeric. Look at the results for
Put BRAND("VW");
You get something similar to:
NOTE: Invalid numeric data, 'VW' , at line 295 column 11.
ERROR: Array subscript out of range at line 295 column 5.
Your log should have had that error.
BTW it really helps to post code and log results in a code box using the {i} icon. copying you code introduced a bunch of . when pasted into a code editor.
Thank you.
I had exactly the log you describe.
But why does it work when I use this code for the subcript:
PUT BRAND(VW);
This works!
Sorry for leaving out the copied code, but I have some compliance issues 🙂
I write from my personal laptop and SAS is installed on my business laptop and without making crazy things from home I cannot easily copy-paste the code.
Check what type are the variables:
VW is probably numeric and its value is either 1 or 2.
MAKE is probably defined as character with values '1' or '2';
When you use strip(var) the output is a character type.
That tells us nothing. Why are you trying to do this?
VW is a variable that's created with the array reference that ends up being circular. You've assigned it a value of 1, then it pulls the first value out of the index. Like I mentioned earlier, this works purely by chance. Change the 1/2 in your array to 5/10 and it won't work anymore.
What problem are you trying to solve with this code.
It might work, but that's really just by chance for your particular example. It's not the correct method to work. Typically you can't access the variable value via an array.
If you want to access the value of a variable look at the VVALUEX function which can work off the variable name, not an index.
No, your use case doesn't make sense to be honest. If the values are fixed, is there a reason you're not using a temporary array.
If you want to solve this problem for learning, feel free, but posting what you're trying to do will help get you an optimal solution.
You reference members of an array with an integer index into the array. Not with a NAME. If you want to reference a variable by name then just reference the variable, there is no need to use an array.
If you need to convert a character variable with the name of a variable into the value of the variable the most direct way is to use the VVALUEX() function, but that would return the value as a character string. If you wanted the value converted back to a number then use INPUT() function.
length vw audi 8 make $32 ;
array brand vw audi (50.5 25.4);
model = 'VW';
mpg = input(vvaluex(model),32.);
Or you could find a method to convert the name to the index to use with the array. For example using the WHICHC() function might work.
model = 'VW';
mpg = brand(whichc(model,'VW','AUDI'));
Try this example:
data _null_;
length vw audi 8 make $32 ;
array brand vw audi (50.5 25.4);
input make ;
mpg1 = input(vvaluex(make),32.);
mpg2 = brand(whichc(make,'VW','AUDI'));
put (_all_) (=);
cards;
VW
AUDI
;;;;
Thanks to all for the many solutions that were provided.
I should explain what I pretended with the array reference.
I create a macro variable that holds the valid working days for 2017. In the real example it's more straightforward than only taking into account the weekdays. Here, for the purpose of my problem, I leave it simplified like this.
DATA _NULL_;
FORMAT DAYS_STRING $10000.;
do MTuWThF = '01Jan2017'd to '31Dec2017'd;
if weekday(MTuWThF) in (2:6) then DO;
DAYS_STRING=CATX(" ", DAYS_STRING, MTuWThF);
OUTPUT;
END;
end ;
CALL SYMPUTX("WDAYS", DAYS_STRING);
RUN;
/* Furthermore I create a dataset with the committee agenda for each brand */
data COMMITTEES ;
input MAKE $ COMMITTEE date9. ROUND $ ;
format COMMITTEE weekdate17. ;
cards ;
VW 12APR2017 1ST
LCV 19APR2017 1ST
SKODA 24MAY2017 1ST
AUDI 12JUL2017 1ST
SEAT 14JUN2017 1ST
VW 30OCT2017 2ND
LCV 25OCT2017 2ND
SKODA 28NOV2017 2ND
AUDI 20DEC2017 2ND
SEAT 15NOV2017 2ND
;
/* Now I want roll back the planning for the prior tasks that lead to each committee. Each brand has different aspects to take into account so that I need to customize the days which are necessary to lay the groundwork for the next event.
I.e. there has to be a time window of 5 days between the internal committee and the final committee.
As the workload and other parameters differ from the first semester to the second, we even have to distinguish between 1st and 2nd semester and fix the dates accordingly.
This makes a case for the use of a multi-dimensional array.
1st dim is the semester,
the second for the 5 brands
and the third for the 3 meetings to be scheduled.
As I had mentioned before, I created a if-then workaround for getting an integer index that I can throw into the array.
The DO LOOP goes back in the calendar until the specified amount of available working days equals the desired number of days between the event and the pre-fixed committee.
-------------------------------------------------------------------------------------------------------------------------------------------
And Tom's nice code, which I tested successfully, would make the program run more efficiently .
Allthough the program now runs like I expect it to do,
I welcome any suggestion that lets me see where I over-complicate things.
I want to learn from the experts.
For example I asked myself if I can declare the multi-dim array with a mixture of integer / intervals and names for the elements like
ARRAY CUST {"1st" "2nd", 5, 3} _TEMPORARY_
(26 32 37
8 13 18
5 10 15
5 10 15
5 10 15
22 60 65
12 17 22
15 20 28
8 13 18
10 15 20);
*/
DATA SCHEDULED;
SET WORK.COMMITTEES;
FORMAT INT_COMMITTEE PRE_COMMITTEE PREPARATION weekdate17.;
ARRAY ACTIVITY (3) $ INT_COMMITTEE PRE_COMMITTEE PREPARATION;
ARRAY BRAND {*} VW SKODA LCV AUDI SEAT (1 2 3 4 5);
ARRAY CUST {2, 5, 3} _TEMPORARY_
(26 32 37
8 13 18
5 10 15
5 10 15
5 10 15
22 60 65
12 17 22
15 20 28
8 13 18
10 15 20);
RETAIN C 0 N 0;
IF STRIP(MAKE)="VW" THEN H1=1;
ELSE IF STRIP(MAKE)="SKODA" THEN H1=2;
ELSE IF STRIP(MAKE)="LCV" THEN H1=3;
ELSE IF STRIP(MAKE)="AUDI" THEN H1=4;
ELSE H1=5;
IF STRIP(ROUND)="1ST" THEN D1=1;
ELSE D1=2;
DO I=1 TO DIM(ACTIVITY);
C=0;
N=0;
DO WHILE (N LT CUST(D1, BRAND(H1),I));
C+1;
IF (COMMITTEE-C) IN (&wdays) THEN N+1;
END;
ACTIVITY(I)=COMMITTEE - C;
END;
KEEP MAKE COMMITTEE INT_COMMITTEE PRE_COMMITTEE PREPARATION;
RUN;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.