Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

☑ This topic is **solved**.
Need further help from the community? Please
sign in and ask a **new** question.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 11-07-2023 03:23 AM
(977 views)

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

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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=;
```

2 REPLIES 2

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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=;
```

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Thank you, this is exactly what I needed!

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

**SAS Innovate 2025** is scheduled for May 6-9 in Orlando, FL. Sign up to be **first to learn** about the agenda and registration!

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.