BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
asasgdsfa
Obsidian | Level 7

Hello

 

May I ask for an advise? I'm trying to read 2D data to proc optmilp and I'm getting error:
"ERROR: The symbol 'student' has no value at line XXX column YYY"

 

I think, it is because I'm trying to load data where not all combinations of indices are present.

student class payment
1 A 1
2 A 2
2 B 3
3 A 4
3 B 5

 

 

So here, you can see that there is not combination of studen 1 in class B. Could this be a reason for the error?
 
Code:
 
proc optmilp;
	set student;
	set <str> class;
	
	num income {student, class};
	read data work.input into [student class] payment = income;
	
	...
quit;
 
I need to have data in the single table and filling missing records (1-B) would probably lead to numerically more difficult task.
I tried to use only a single index (composed of student-class) and it worked, but for the problem, I need to access these two indexes independently.
1 ACCEPTED SOLUTION

Accepted Solutions
ChanceTGardener
SAS Employee

A couple of suggestions:

 

   1.  You're calling the OPTMILP procedure, but the syntax more closely resembles the OPTMODEL procedure. Change PROC OPTMILP to PROC OPTMODEL

 

*proc optmilp;

proc optmodel;

    2.  Declare a set of ARCS indexed by both students and classes. Declare a payment parameter indexed by ARCS, and read the table into the OPTMODEL procedure. 

set <num,str> ARCS;

num payment{ARCS};

read data work.input into ARCS = [student class] payment;

    3.  To create a set of STUDENTS and a set of CLASSES from the ARCS set, use the setof{ } operator.

set STUDENTS = setof{<s,c> in ARCS} s;

set CLASSES = setof{<s,c> in ARCS} c;

 Full code below:

 

data work.input;
 input student class $ payment;
datalines;
1 A 1
2 A 2
2 B 3
3 A 4
3 B 5
;

*proc optmilp;
proc optmodel;

set <num,str> ARCS;

num payment{ARCS};

read data work.input into ARCS = [student class] payment;

set STUDENTS = setof{<s,c> in ARCS} s;
set CLASSES = setof{<s,c> in ARCS} c;

/* write the elements of each set to the log */
put ARCS=;
put STUDENTS=;
put CLASSES=;

/* print payment to the results viewer */
print payment;

Structuring it this way allows you to sum across all students, or sum across all classes later in the program without the missing element <1,B> causing an issue:

num total_by_class{c in CLASSES} = sum{<s,(c)> in ARCS} payment[s,c];

num total_by_student{s in STUDENTS} = sum{<(s),c> in ARCS} payment[s,c];

print total_by_class;
print total_by_student;

The MISSINGS set below captures all of the student-class combinations not present in your data, and as a result, not part of the new calculated parameters above. 

set MISSINGS = (STUDENTS cross CLASSES) diff ARCS; 
put MISSINGS=;

View solution in original post

2 REPLIES 2
ChanceTGardener
SAS Employee

A couple of suggestions:

 

   1.  You're calling the OPTMILP procedure, but the syntax more closely resembles the OPTMODEL procedure. Change PROC OPTMILP to PROC OPTMODEL

 

*proc optmilp;

proc optmodel;

    2.  Declare a set of ARCS indexed by both students and classes. Declare a payment parameter indexed by ARCS, and read the table into the OPTMODEL procedure. 

set <num,str> ARCS;

num payment{ARCS};

read data work.input into ARCS = [student class] payment;

    3.  To create a set of STUDENTS and a set of CLASSES from the ARCS set, use the setof{ } operator.

set STUDENTS = setof{<s,c> in ARCS} s;

set CLASSES = setof{<s,c> in ARCS} c;

 Full code below:

 

data work.input;
 input student class $ payment;
datalines;
1 A 1
2 A 2
2 B 3
3 A 4
3 B 5
;

*proc optmilp;
proc optmodel;

set <num,str> ARCS;

num payment{ARCS};

read data work.input into ARCS = [student class] payment;

set STUDENTS = setof{<s,c> in ARCS} s;
set CLASSES = setof{<s,c> in ARCS} c;

/* write the elements of each set to the log */
put ARCS=;
put STUDENTS=;
put CLASSES=;

/* print payment to the results viewer */
print payment;

Structuring it this way allows you to sum across all students, or sum across all classes later in the program without the missing element <1,B> causing an issue:

num total_by_class{c in CLASSES} = sum{<s,(c)> in ARCS} payment[s,c];

num total_by_student{s in STUDENTS} = sum{<(s),c> in ARCS} payment[s,c];

print total_by_class;
print total_by_student;

The MISSINGS set below captures all of the student-class combinations not present in your data, and as a result, not part of the new calculated parameters above. 

set MISSINGS = (STUDENTS cross CLASSES) diff ARCS; 
put MISSINGS=;
asasgdsfa
Obsidian | Level 7

Thank you, this is exactly what I needed!

(Your are correct, it's optmodel, but I was thinking about something else, sorry.)

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 2 replies
  • 775 views
  • 2 likes
  • 2 in conversation