BookmarkSubscribeRSS Feed
wjgolembos
Calcite | Level 5

"Create Data" no longer works in a Proc OPTMODEL statement that has worked w/o issue, over several years.

 

A Colleague of mine thinks it could be related to change(s) in SAS v9.4:

       -  I have not seen anything in SAS Community, or, in the Release Notes indicative of such an issue 

       -  Might anyone be familiar with the error code(s) in the attached file, and what edits I need to make?

 

Thank You.

 

Bill G (WJG)

w/ attachment

 

1888
1889  PROC optmodel;
NOTE: Writing HTML Body file: sashtml1.htm
1890  /*  Declare Sets and Parameters  */
1891      set ACCOUNTS;
1892      set RISK_CLASS;
1893      set <str> LOCATIONS;
1894      num est_write_off {ACCOUNTS}, est_payment {ACCOUNTS};
1895      num risk_segment {ACCOUNTS};
1896      num max_jobs {RISK_CLASS};
1897      num min_restrictions {LOCATIONS};
1898      num max_restrictions {LOCATIONS};
1899      str service_center {ACCOUNTS};
1900
1901      set <str> MCSV;
1902      num min_mcsv {MCSV};
1903      num max_mcsv {MCSV};
1904      str man_proc_q {ACCOUNTS};
1905
1906      set <str> CUST_CLASS;
1907      num min_class_limits {CUST_CLASS};
1908      num max_class_limits {CUST_CLASS};
1909      str customer_class {ACCOUNTS};
1910
1911  /*  Read Data from SAS Data Sets  */
1912      read data Summary into RISK_CLASS=[New_Rank] max_jobs=Daily_Jobs;
NOTE: There were 7 observations read from the data set WORK.SUMMARY.
1913
1914      read data Location_Restrictions into LOCATIONS=[Service_Center] min_restrictions=min
1914! max_restrictions=max;
NOTE: There were 5 observations read from the data set WORK.LOCATION_RESTRICTIONS.
1915      *print restrictions;
1916
1917      read data Class_Restrictions into CUST_CLASS=[Res_Com] min_class_limits=Min
1917! max_class_limits=Max;
NOTE: There were 2 observations read from the data set WORK.CLASS_RESTRICTIONS.
1918      *print class_limits;
1919
1920  /*DATA Manual_Processes;
1921      infile datalines delimiter=',';
1922      length Manual_Proc $6;
1923      input Manual_Proc Max;
1924      put Manual_Proc Max;
1925  Datalines;
1926  Max_MC,60
1927  Max_SV,35
1928  ;*/
1929
1930      read data Manual_Processes into MCSV=[Manual_Proc] min_mcsv=Min max_mcsv=Max;
NOTE: There were 3 observations read from the data set WORK.MANUAL_PROCESSES.
1931      *print max_mcsv;
1932
1933      read data Selection_File into ACCOUNTS=[Acct_ID] est_write_off=EstWriteOff
1933! est_payment=EstPayment risk_segment=New_Rank service_center=Service_Center
1933! customer_class=Res_Com man_proc_q=Manual_Process;
WARNING: Duplicate key <2023446720> was read at observation 280.
WARNING: Duplicate key <6280665934> was read at observation 650.
WARNING: Duplicate key <8831810000> was read at observation 697.
WARNING: Duplicate key <9821304710> was read at observation 751.
WARNING: Duplicate key <3802555737> was read at observation 763.
WARNING: Duplicate key <5211474099> was read at observation 818.
WARNING: Duplicate key <5176820000> was read at observation 871.
WARNING: Duplicate key <7671540588> was read at observation 966.
WARNING: Duplicate key <8444959622> was read at observation 967.
WARNING: Duplicate key <9938059754> was read at observation 1057.
WARNING: Duplicate key <1154321000> was read at observation 1104.
WARNING: Duplicate key <135411000> was read at observation 1152.
WARNING: Duplicate key <1560331720> was read at observation 1224.
WARNING: Duplicate key <4716410000> was read at observation 1373.
WARNING: Duplicate key <2701757317> was read at observation 1375.
WARNING: Duplicate key <8147351370> was read at observation 1416.
WARNING: Duplicate key <649269833> was read at observation 1426.
WARNING: Duplicate key <9303006735> was read at observation 1434.
WARNING: Duplicate key <2909628081> was read at observation 1455.
WARNING: Duplicate key <97465376> was read at observation 1458.
WARNING: Duplicate key <6219611051> was read at observation 1598.
NOTE: 21 duplicate keys were read.
NOTE: There were 1598 observations read from the data set WORK.SELECTION_FILE.
1934
1935      *print risk_segment est_write_off est_payment service_center customer_class man_proc_q;
1936      *print max_jobs;
1937
1938  /*  Declare Variables  */
1939      var Target {ACCOUNTS} binary;
1940
1941      impvar NumTarget {r in RISK_CLASS} =
1942          sum {a in ACCOUNTS: risk_segment[a] = r} Target[a];
1943
1944      impvar NumRestrict {s in LOCATIONS} =
1945          sum {a in ACCOUNTS: service_center[a] = s} Target[a];
1946
1947      impvar NumClassRestrict {c in CUST_CLASS} =
1948          sum {a in ACCOUNTS: customer_class[a] = c} Target[a];
1949
1950      impvar NumMCSV {c in MCSV} =
1951          sum {a in ACCOUNTS: man_proc_q[a] = c} Target[a];
1952
1953      impvar Payments =
1954          sum {a in ACCOUNTS} est_payment[a] * Target[a];
1955
1956      impvar WriteOffs =
1957          sum {a in ACCOUNTS} est_write_off[a] * Target[a];
1958
1959  /*  Declase Constraints  */
1960      *****con Max_Terms {r in RISK_CLASS}: NumTarget[r] = max_jobs[r];
1961
1962      con Restrict {s in LOCATIONS}: min_restrictions[s] <= NumRestrict[s] <= max_restrictions[s];
1963
1964      con ClassRestrict {c in CUST_CLASS}: min_class_limits[c] <= NumClassRestrict[c] <=
1964! max_class_limits[c];
1965
1966      con MCSVRestrict {c in MCSV}: min_mcsv[c]<= NumMCSV[c] <= max_mcsv[c];
1967
1968      *con Max_WO_LB: sum {a in ACCOUNTS} est_write_off[a] * Target[a]
1969          >= &DAILY_WRITE_OFFS. - (&WO_Range. * 1);
1970
1971      *con Max_WO_UB: sum {a in ACCOUNTS} est_write_off[a] * Target[a]
1972          <= &DAILY_WRITE_OFFS. + &WO_Range.;
1973
1974  /*  Declare Objective  */
1975      *max ReserveImpact = Payments - WriteOffs;
1976      *min ReserveImpact = WriteOffs;
1977
1978      max ReserveImpact = WriteOffs;
1979
1980      solve with milp;
NOTE: Problem generation will use 4 threads.
NOTE: The constraint 'MCSVRestrict[MC]' is empty.
NOTE: The problem has 1577 variables (0 free, 0 fixed).
NOTE: The problem uses 11 implicit variables.
NOTE: The problem has 1577 binary and 0 integer variables.
NOTE: The problem has 10 linear constraints (0 LE, 0 EQ, 0 GE, 10 range).
NOTE: The problem has 4706 linear constraint coefficients.
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The initial MILP heuristics are applied.
NOTE: The MILP presolver value AUTOMATIC is applied.
NOTE: The MILP presolver removed 646 variables and 8 constraints.
NOTE: The MILP presolver removed 3775 constraint coefficients.
NOTE: The MILP presolver modified 0 constraint coefficients.
NOTE: The presolved problem has 931 variables, 2 constraints, and 931 constraint coefficients.
NOTE: The MILP solver is called.
NOTE: The parallel Branch and Cut algorithm is used.
NOTE: The Branch and Cut algorithm is using up to 4 threads.
NOTE: The problem has a decomposable structure with 2 blocks. The largest block covers 50.00% of the
      constraints in the problem. The DECOMP option with METHOD=CONCOMP is recommended for solving
      problems with this structure.
          Node   Active   Sols    BestInteger      BestBound      Gap    Time
             0        1      2         686540         686540    0.00%       0
             0        0      2         686540         686540    0.00%       0
NOTE: Optimal.
NOTE: Objective = 686539.96.
1981      *solve with milp / relobjgap=1e-4;
1982
1983  /* Create Dataset */
1984      create data Customers_Offered from [ACCOUNTS]=
                                              --------
                                              708
1985          {a in ACCOUNTS: Target[a]>1e-4} RISK_CLASS=risk_segment;
                            -
                            875
                            515
NOTE 708-782: The name 'ACCOUNTS' hides an outer declaration.

ERROR 875-782: A key set expression may not depend on key column values like 'ACCOUNTS'.

ERROR 515-782: An indexing set subexpression may not be a scalar.

1986  quit;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE OPTMODEL used (Total process time):
      real time           0.51 seconds
      user cpu time       0.21 seconds
      system cpu time     0.31 seconds
      memory              87619.65k
      OS Memory           103480.00k
      Timestamp           03/29/2022 01:09:01 PM
      Step Count                        150  Switch Count  10
3 REPLIES 3
RobPratt
SAS Super FREQ

Indeed, in SAS 9.4M5 (released in 2017) there was a change to the implementation of the CREATE DATA statement because it did not quite match the behavior described in the documentation.  Here are three alternative ways to avoid the ERROR just by changing your CREATE DATA statement.

 

1. Rename the data set variable to ACCOUNT instead of ACCOUNTS:

   create data Customers_Offered from [ACCOUNT]=
      {a in ACCOUNTS: Target[a]>1e-4} RISK_CLASS=risk_segment;

2. If you really want the data set variable name to be ACCOUNTS, use the RENAME= data set option:

   create data Customers_Offered(rename=(ACCOUNT=ACCOUNTS)) from [account]=
      {a in ACCOUNTS: Target[a]>1e-4} RISK_CLASS=risk_segment;

3. Or use a COL expression:

   create data Customers_Offered from [col("ACCOUNTS")]=
      {a in ACCOUNTS: Target[a]>1e-4} RISK_CLASS=risk_segment;
wjgolembos
Calcite | Level 5

Awesome!

 

TY for the quick reply, Super Freq.

 

I will test each of your three solutions, ASAP.

 

[I love your Moniker].

 

Bill G.

RobPratt
SAS Super FREQ

Glad to help.  Besides me, several other SAS employees have also been designated as Super FREQs: https://communities.sas.com/t5/Community-Memo/Meet-the-Super-FREQs/ba-p/291008

SAS Innovate 2025: Save the Date

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

Save the date!

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
  • 3 replies
  • 1085 views
  • 1 like
  • 2 in conversation