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

hi, guys. I am learning nlmeans macro to estimate and test the difference in rates. I use to call NLmeans macro. But there are a lot of errors in the code, and I don't know why. Can anyone help me?

By the way, my code was copied from "Macro Argument List Start" to the SAS editor and ran to implement the call to NLmeans. My code is as follows:

data insure524;
input n c age;
ln=log(n);
obsRate=c/n;
datalines;
500 42 1
400 101 2
;
proc genmod data=insure524;
class age;
model c=age/dist=poisson offset=ln link=log;
lsmeans age/e diff exp cl;
ods output coef=coeffs;
store out=insmodel;
run;

 

%NLMeans(instore=insmodel, coef=coeffs, link=log, title=Difference of Age Rates);

And the SAS codes of Nlmeans macro  are:

%*===================== Macro Argument List Start =====================;

%macro NLMeans(
version,    /* Any specified text as first argument displays the      */
            /* current version of the NLMeans macro in the log.       */
instore=,   /* Specifies the fitted model that was saved using the    */
            /* STORE statement in the modeling procedure. The OUT=    */
            /* option in the STORE statement saves the model in a     */
            /* file known as an item store. This is the preferred     */ 
            /* method for providing the required model information.   */
            /* However, if the modeling procedure does not offer the  */
            /* STORE statement, then you might be able to use the     */
            /* inest= and incovb= parameters.                         */
inest=,     /* Specifies the data set of parameter estimates saved    */
            /* using an ODS OUTPUT statement in the modeling          */
            /* procedure. The parameter estimates of the model should */
            /* be stored in a variable named ESTIMATE in this data    */
            /* set. An error is issued if the ESTIMATE variable is    */
            /* not found.                                             */
incovb=,    /* Specifies the data set containing the variance-        */
            /* covariance matrix of model parameters saved using an   */
            /* ODS OUTPUT statement in the modeling procedure.        */
            /* Typically, an option such as COVB is required in the   */
            /* modeling procedure to make this matrix available for   */
            /* saving. If the saved data set contains numeric         */
            /* variables other than those containing the covariance   */
            /* matrix, they should be removed before specifying the   */
            /* data set in this macro parameter in order to avoid a   */
            /* compatibility error. The incovb= data set should have  */
            /* the same number of observations (rows) and variables   */
            /* (columns) as the number of rows in the inest= data set */
            /* in order to be compatible.                             */
coef=,      /* Specifies the data set of estimate coefficients saved  */
            /* using an ODS OUTPUT statement in the modeling          */
            /* procedure. The required table must first be produced   */
            /* by including the E option in the LSMEANS, SLICE, or    */
            /* ESTIMATE statement in the modeling procedure. The      */
            /* table name is typically Coef and can be saved in a     */
            /* data set by specifying: ods output Coef=data-set-name; */
link=,      /* Specifies the link function used in the modeling       */
            /* procedure, typically in the LINK= option in the MODEL  */
            /* statement. Note that for models fit by PROC PROBIT     */
            /* which specifies the link with the DIST= option,        */
            /* specify link=probit or cumprobit when DIST=NORMAL;     */
            /* link=logit or cumlogit when DIST=LOGISTIC; or link=cll */
            /* or cumcll when DIST=EXTREME or GOMPERTZ.               */
diff=all,   /* To estimate and test all pairwise differences of means,*/
            /* specify diff=all. Sequential differences of means      */
            /* (mean1-mean2, mean2-mean3, ...) are provided when      */
            /* diff=seq. To obtain all differences with a control     */
            /* level, specify diff=number, where number is the        */
            /* position of the control level in the ordered list of   */
            /* levels shown in the results from the modeling          */
            /* procedure. For example, if level A is the control in a */
            /* variable whose levels are shown in the order A, B, C,  */
            /* then specify diff=1. When there are multiple sets of   */
            /* estimates from the modeling procedure (presented in    */
            /* multiple tables), such as when the SLICE / E SLICEBY=  */
            /* statement is used or when multiple LSMEANS /E,         */
            /* SLICE /E, or ESTIMATE /E statements are used, then you */
            /* can either specify a single type to apply to all       */
            /* estimate sets, or a list of types to apply different   */
            /* types to the sets. If diff= is omitted, all pairwise   */
            /* differences are done for all sets (diff=all).          */
contrasts=, /* Specifies an optional data of coefficients defining    */
            /* contrasts among the estimates in each set of estimates.*/
            /* The specified data set must contain a variable named   */
            /* SET and k variables named K1, K2, ... , Kk, where k is */
            /* the number of Row variables in coef= data set.         */ 
            /* Optionally, a LABEL variable can be included to label  */
            /* each of the specified contrasts. For a given           */
            /* row in the data set, the value of SET indicates        */
            /* the set of estimates that the contrast in that row     */
            /* applies to. The SET value must match one of the values */
            /* of the LMatrix variable in the coef= data set. The K   */
            /* variables correspond to the Row variables in the coef= */
            /* data set which define each estimate. For multinomial   */
            /* models, k=mf where m is the number of estimates        */
            /* requested in each response function and f is the       */
            /* number of response functions. For link=glogit models,  */
            /* k=mf+m. The additional set of m variables correspond   */
            /* to the last response level. See the description of     */
            /* options=ratio for limitations on the contrast          */
            /* coefficients when mean ratios are desired. If          */
            /* contrasts= and diff= are both specified, diff= is      */
            /* ignored.                                               */
df=,        /* Specifies the degrees of freedom to be used in the     */
            /* tests and confidence intervals computed for the        */
            /* estimated functions. If omitted, large-sample Wald     */
            /* statistics are given. The degrees of freedom for       */
            /* testing a linear combination of parameters in a linear */
            /* model would typically be the number of observations    */
            /* used in fitting the model minus the number of          */
            /* parameters estimated in the model - essentially, the   */
            /* error degrees of freedom.                              */
alpha=0.05, /* Specifies the alpha level to be used in computing      */
            /* confidence limits. If omitted, alpha=0.05.             */
title=,     /* Specifies a title for the table(s) of results. The     */
            /* title must not contain quotes (" or '), ampersands (&),*/ 
            /* commas, or parentheses. If omitted,                    */
            /* title=Nonlinear Function Estimate.                     */
options=NOJOINT NONAMES NOREVERSE NORATIO DIFINFNS NOAPPEND        /* */
            /* Use options= to enable or disable any of several       */
            /* binary options: JOINT|NOJOINT, NAMES|NONAMES,          */
            /* REVERSE|NOREVERSE, RATIO|NORATIO, DIFINFNS|DIFALL.     */
            /* JOINT combines multiple sets of estimates into a       */
            /* single set before differencing or applying contrasts.  */
            /* NAMES displays the names of the model parameters used  */
            /* by the NLEstimate macro. REVERSE reverses the          */
            /* direction of differencing done by diff=. REVERSE is    */
            /* ignored when contrasts= is specified. RATIO requests   */
            /* estimation of ratios rather than differences of pairs  */
            /* of means. RATIO can be used with diff= or contrasts=,  */
            /* but with contrasts= each contrast must specify exactly */
            /* one 1 coefficient to select the numerator, one -1      */
            /* coefficient to select the denominator, and 0           */
            /* coefficients otherwise. For multinomial models, DIFALL */
            /* applies the differencing type specified in diff=       */
            /* across all estimates rather than within the response   */
            /* functions as done by DIFINFNS. This option is ignored  */
            /* for nonmultinomial models. APPEND merges results from  */
            /* all estimate sets into a single results data set named */
            /* EST_ALL. NOAPPEND saves results sets in separate data  */
            /* sets (EST1, EST2, ...). The last results set is always */
            /* saved in data set EST as well. If not specified,       */
            /* options=nojoint nonames noreverse noratio difinfns     */
            /* noappend.                                              */
) / minoperator;

;*=========================== Macro Start =============================;

%local notesopt; 
%let notesopt = %sysfunc(getoption(notes));
%let timenlm = %sysfunc(datetime());
%let _version=1.04;
%if &version ne %then %put NOTE: &sysmacroname macro Version &_version..;
%if %index(%upcase(&version),DEBUG) %then %do;
  options notes mprint
    %if %index(%upcase(&version),DEBUG2) %then mlogic symbolgen;
  ;
  ods select all;
  %put _user_;
  %let dbgopt=debug,;
  %if %index(%upcase(&version),DEBUG2) %then %let dbgopt=debug2,;
%end;
%else %do;
  options nonotes nomprint nomlogic nosymbolgen;
  ods exclude all;
  %if &version ne %then %let dbgopt=v,;
  %else %let dbgopt=;
%end;

/* Check for newer version */
%let _notfound=0;
filename _ver url 'http://ftp.sas.com/techsup/download/stat/versions.dat' 
	 termstr=crlf;
data _null_;
  infile _ver end=_eof;
  input name:$15. ver;
  if upcase(name)="&sysmacroname" then do;
    call symput("_newver",ver); stop;
  end;
  if _eof then call symput("_notfound",1);
  run;
options notes;
%if &syserr ne 0 or &_notfound=1 %then
  %put NOTE: Unable to check for newer version of &sysmacroname macro.;
%else %if %sysevalf(&_newver > &_version) %then %do;
  %put NOTE: A newer version of the &sysmacroname macro is available at;
  %put NOTE- this location: http://support.sas.com/ ;
%end;
%if %index(%upcase(&version),DEBUG)=0 %then options nonotes;;

/* Check inputs */
%if (&instore= and &inest= and &incovb=) or
    (&instore= and (&inest= or &incovb=)) %then %do;
  %put ERROR: Either INSTORE= or both INEST= and INCOVB= must be specified.;
  %goto exit;
%end;
%if &coef= or %sysfunc(exist(&coef)) ne 1 %then %do;
  %put ERROR: COEF= data set not specified or not found.;
  %goto exit;
%end;
%if &contrasts ne and %sysfunc(exist(&contrasts)) ne 1 %then %do;
  %put ERROR: CONTRASTS= data set not found.;
  %goto exit;
%end;
/* Verify COEF= data set has necessary variables */
%let status=ok;
%let dsid=%sysfunc(open(&coef));
%if &dsid %then %do;
  %if %sysfunc(varnum(&dsid,LMATRIX))=0 or %sysfunc(varnum(&dsid,ROW1))=0 or
  (%sysfunc(varnum(&dsid,PARAMETER))=0 and %sysfunc(varnum(&dsid,EFFECT))=0)
  %then %do;
    %put ERROR: Invalid COEF= data set. At least one variable Parameter (or;
    %put ERROR- Effect), LMatrix, or Row1 not found.;
    %let status=input_err;
  %end;
  %let rc=%sysfunc(close(&dsid)); 
  %if &status=input_err %then %goto exit;
%end;
%else %do;
  %put ERROR: Could not open COEF= data set.;
  %goto exit;
%end;

%let validopts=JOINT NOJOINT NAMES NONAMES REVERSE NOREVERSE RATIO NORATIO
DIFINFNS DIFALL APPEND NOAPPEND;
%let joint=0; %let names=0; %let rdiff=0; %let ratio=0; %let difall=0;
%let append=0;
%let i=1;
%do %while (%scan(&options,&i) ne %str() );
   %let option&i=%upcase(%scan(&options,&i));
   %if &&option&i=JOINT %then %let joint=1;
   %else %if &&option&i=NAMES %then %let names=1;
   %else %if &&option&i=REVERSE %then %let rdiff=1;
   %else %if &&option&i=RATIO %then %let ratio=1;
   %else %if &&option&i=DIFALL %then %let difall=1;
   %else %if &&option&i=APPEND %then %let append=1;
   %else %do;
    %let chk=%eval(&&option&i in &validopts);
    %if not &chk %then %do;
      %put ERROR: Valid values of OPTIONS= are &validopts..;
      %goto exit;
    %end;
   %end;
   %let i=%eval(&i+1);
%end;

%if %index(%quote(&title),%str(%")) or %index(%quote(&title),%str(%')) 
%then %do;
  %put ERROR: Do not use quotes (%str(%") or %str(%')) in TITLE=.;
  %goto exit;
%end;
%if &df= %then %let dfopt=;
%else %let dfopt=, df=&df;
%if &alpha= %then %let alphaopt=;
%else %let alphaopt=, alpha=α
%if %quote(&title)= %then %let ttlopt=;
%else %let ttlopt=, title=%quote(&title);
%if &names=1 %then %let namopt=;
%else %let namopt=, listnames=no;
%if &rdiff %then %do;
  %let locode=-1; %let hicode=1;
%end;
%else %do; 
  %let locode=1; %let hicode=-1;
%end;

/* Determine inverse link function */
%let link=%quote(%upcase(&link));
%if &link= %then %do;
  %put ERROR: The LINK= option is required.;
  %goto exit;
%end;
%else %if &link=LOGIT or &link=CUMLOGIT or &link=CLOGIT %then 
  %let ilink="logistic("||trim(left(exp))||")";
%else %if &link=PROBIT or &link=CUMPROBIT or &link=CPROBIT %then 
  %let ilink="probnorm("||trim(left(exp))||")";
%else %if &link=CLL or &link=CLOGLOG or &link=CUMCLL or &link=CCLL 
or &link=CCLOGLOG or &link=CUMCLOGLOG %then 
  %let ilink="(1-exp(-exp("||trim(left(exp))||")))";
%else %if &link=LOGLOG or &link=CUMLOGLOG %then 
  %let ilink="exp(-exp(-("||trim(left(exp))||")))";
%else %if &link=LOG or &link=GLOGIT %then 
  %let ilink="exp("||trim(left(exp))||")";
%else %if %substr(&link,1,3)=POW %then %do;
  %let power=%quote(%substr(&link,6));
  %if &power=0 %then %let ilink="exp("||trim(left(exp))||")";
  %else %let ilink="exp(log("||trim(left(exp))||")/&power)";
%end;
%else %if %upcase(&link)=IDENTITY %then %do;
  options notes;
  %put NOTE: This macro is not needed when LINK=IDENTITY.; 
  %put NOTE- Use results of LSMEANS, SLICE or ESTIMATE.;
  options nonotes;
  %goto exit;
%end;
%else %do;
  %put ERROR: Valid LINK= values are LOG, LOGIT, CUMLOGIT, PROBIT, ;
  %put ERROR- CUMPROBIT, CLL, CUMCLL, LOGLOG, CUMLOGLOG, GLOGIT, ;
  %put ERROR- or POWERx where x is a number.;
  %goto exit;
%end;
%if &difall and &link=GLOGIT %then %do;
  %put ERROR: OPTIONS=DIFALL cannot be used with LINK=GLOGIT.;
  %goto exit;
%end;

/* Determine number of response functions for multinomial models */
%let nfn=1;
%let cumlinks=CUMLOGIT CLOGIT CUMPROBIT CPROBIT CUMCLL CCLL CCLOGLOG 
              CUMCLOGLOG CUMLOGLOG GLOGIT;
%let cumchk=%eval(&link in &cumlinks);
%if &cumchk %then %do;
  data _null_;
   set &coef end=eof;
   if index(Parameter,"Intercept") or index(Effect,"Intercept") then nfn+1;
   else do;
     call symput('nfn',cats(nfn));
     stop;
   end;
   run;
%end;

/* Get number of sets of estimates */
%if &joint %then %do;
   %let nsets=1; %let set1=1;
   proc transpose data=&coef out=_coef(drop=_name_); 
    by LMatrix;
    var row:; 
    run;
   proc transpose data=_coef out=_coef(drop=_name_) prefix=Row; 
    var col:; 
    run;
   data _coef; set _coef;
    LMatrix=1;
    run;
%end;
%else %do;
   proc freq data=&coef nlevels; 
     table LMatrix / out=_setnums noprint; 
     ods output nlevels=_nlvl; 
     run;
   data _null_; 
     set _nlvl; 
     call symput('nsets',cats(nlevels)); 
     run;
   data _null_; 
     set _setnums; 
     call symput(cats('set',_n_),cats(lmatrix)); 
     run;
   data _coef;
     set &coef;
     run;
%end;

%if &contrasts= %then %do;
   %let diff=%upcase(&diff);
   %let ndifvals=%sysfunc(countw(&diff));
   %if &ndifvals ne 1 and &ndifvals ne &nsets %then %do;
     %put ERROR: There are &nsets sets of estimates. Specify a single value;
     %put ERROR- in DIFF= to apply to all sets, or one value for each set.;
     %put ERROR- Valid values are ALL, SEQ, or a positive integer.;
     %goto exit;
   %end;
   %let i=1; 
   %do %while (%scan(&diff,&i) ne %str() );
      %let diferr=0;
      %let setdif&i=%scan(&diff,&i);
      %if &&setdif&i ne ALL and &&setdif&i ne SEQ %then %do;
        %let diferr=1;
        %if %sysevalf(&&setdif&i>0 and &&setdif&i<1e8) %then %do;
          %if %sysevalf(%sysfunc(mod(&&setdif&i,1))=0) %then %let diferr=0;
        %end;
        %if &diferr %then %do;
          %put ERROR: Invalid DIFF= value found. Valid values are ALL, SEQ or;
          %put ERROR- a positive integer.;
          %goto exit;
        %end;
      %end;
      %let i=%eval(&i+1);
   %end;
%end;

/* Process each set of estimates in COEF= data set */
%do s=1 %to &nsets;

/* Construct mean expressions for NLEstimate macro */
proc transpose data=_coef
  %if &joint=0 %then (where=(LMatrix=&&set&s)); 
  out=_ct(keep=col: where=(col1 ne .)); 
 by lmatrix; 
 var row:; 
 run;
data _glognum(keep=fn1) _glogden(keep=sum);
 set _ct nobs=nlsm end=last;
 array lb (*) col:;
 array fn (&nfn) $32767;
 length exp sum sum1 $32767;
 do i=1 to &nfn;    *initialize &nfn fns for each row in _ct;
  if lb(1) ne 0 then fn(i)=catx("*",lb(1),cats("B_p",i));
 end;
 do i=2 to dim(lb); *cols;
  do j=1 to &nfn;   *fns;
   if lb(i) ne 0 then
   fn(j)=catx("+",fn(j),catx("*",lb(i),cats("B_p",i+j-1)));
  end;
 end;
 do i=1 to &nfn;
  exp=fn(i); fn(i)=&ilink;
  if i=1 then sum1=fn(i);
  else sum1=catx("+",sum1,fn(i));
 end;
 sum="(1+"||trim(left(sum1))||")";
 call symput("nlsm",cats(nlsm));
 output _glognum;
 if _n_<=nlsm/&nfn then output _glogden;
 %if &link=GLOGIT %then %do;
   if last and &nfn>1 then do;
     fn1="1"; 
     do i=1 to nlsm/&nfn;
       output _glognum;
     end;
   end;
 %end;
 run;
data _prexp;
 length exp $32767;
 %if &link=GLOGIT %then %do;
   set %do i=1 %to &nfn+1; _glogden %end;
   ;
   merge _glognum;
   exp=catx("/",fn1,sum);
   %if &ratio %then exp="("||trim(left(exp))||")";;
 %end;
 %else %do;
   set _glognum;
   exp=fn1;
 %end;
 keep exp;
 run;
proc transpose data=_prexp out=_lbt(keep=col:); 
 var exp; 
 run;

/* With DIFALL: don't restrict differencing to be within response functions */
%if &difall %then %let nfn=1;

/* Number of estimates per response function in multinomial models */ 
%let nperfn=%sysevalf(&nlsm/&nfn);
 
/* Comparisons: pairwise diffs, diff with control, or input contrasts */ 
%if &link=GLOGIT and &nfn>1 %then %do;
  %let nk=%sysevalf((&nfn+1)*&nperfn);
  %let badglgcoef=0;
  %if %sysevalf(%sysfunc(mod(&nperfn,1)) ne 0) %then %let badglgcoef=1;
  %else %do;
   data 
    %do f=1 %to &nfn; 
     %let first=%eval((&f-1)*&nperfn+1);
     %let last=%eval(&f*&nperfn);
     _glg&f(keep=row&first - row&last) 
    %end;
    ;
    set _coef
     %if &joint=0 %then (where=(LMatrix=&&set&s)); 
    ;
    %do i=1 %to &nfn-1;
     if mod(_n_,&nfn)=&i then output _glg&i;
    %end;
    if mod(_n_,&nfn)=0 then output _glg&nfn;
    run;
   %do f=2 %to &nfn;
    proc compare base=_glg1 compare=_glg&f noprint out=_glgcomp outnoequal;
     var row1-row&nperfn; 
     %let first=%eval((&f-1)*&nperfn+1);
     %let last=%eval(&f*&nperfn);
     with row&first-row&last;
     run;
     %let uneq=0;
    data _null_;
     dsid=open("_glgcomp");
     nobs=attrn(dsid, "nobs");
     if nobs>0 then call symput ("uneq",1);
     rc=close(dsid);
     run;
    %if &uneq %then %let badglgcoef=1;
   %end;
  %end;
  %if &badglgcoef %then %do;
    %put ERROR: For LINK=GLOGIT, the requested estimates must be estimated in;
    %put ERROR- each of the &nfn logits. If the ESTIMATE statement was used,;
    %put ERROR- the CATEGORY=JOINT option is required.;
    %put ERROR: The above message is for estimate set &&set&s...;
    %goto endset;
  %end;
%end;
%else %let nk=&nlsm;

%if &nperfn=1 %then %do;
  %put ERROR: Only one estimate - no differencing possible;
  %put ERROR: The above message is for estimate set &&set&s...;
  %goto endset;
%end;

%let label=0;
%if &contrasts= %then %do;
 %if &ndifvals=1 %then %let setdif&s=&setdif1;
 %if %sysevalf(&&setdif&s>0 and &&setdif&s<1e8) %then %do;
  %if &&setdif&s>&nperfn %then %do;
 %put ERROR: The DIFF= value, &&setdif&s, for estimate set &&set&s must be an;
 %put ERROR- integer between 1 to the the number of estimates, &nperfn..;
    %goto exit;
  %end;
 %end;

 data _cntrs(keep=k:);
  array k (&nk) (&nk*0);
  do f=1 to &nfn
    %if &link=GLOGIT and &nfn>1 %then +1;
  ;
    first=(f-1)*&nperfn+1;
    last=f*&nperfn;

    %if &&setdif&s=ALL %then %do;
    do i=first to last-1;
     do j=i+1 to last;
      do h=1 to last;
       if h=i then k(h)=&locode;
       else if h=j then k(h)=&hicode;
       else k(h)=0;
      end;
      output;
     end;
    end;
    %end;
    %else %if &&setdif&s=SEQ %then %do;
    do i=first to last-1;
     do h=1 to last;
      if h=i then k(h)=&locode;
      else if h=i+1 then k(h)=&hicode;
      else k(h)=0;
     end;
     output;
    end;
    %end;
    %else %do;
    do j=first to last;
     do h=1 to last;
      if h=(first-1)+&&setdif&s then k(h)=&locode;
      else if h=j then k(h)=&hicode;
      else k(h)=0;
     end;
     if j ne (first-1)+&&setdif&s then output;
    end;
    %end;

  end;
 run;
 %let noobs=0;
 data _null_;
  dsid=open("_cntrs");
  nobs=attrn(dsid, "nobs");
  if nobs=0 then call symput ("noobs",1);
  rc=close(dsid);
  run;
  %if &noobs %then %do;
   %put ERROR: Could not produce differencing coefficients. If a multinomial;
   %put ERROR- model was used you might need to specify OPTIONS=DIFALL.;
   %put ERROR: The above message is for estimate set &&set&s...;
   %goto endset;
  %end;
%end;
%else %do;
   %let misscoef=0; %let miss_set=0;
   data _cntrs; 
    set &contrasts;
    array k (*) k:; nk=dim(k);
    if set=&&set&s;
    if (nk-nmiss(of k:))<&nk then do;
       call symput("misscoef",1);
       stop;
    end;
    run;
   data _null_;
    dsid=open("_cntrs");
    nobs=attrn(dsid, "nobs");
    if nobs=0 then call symput ("miss_set",1);
    if varnum(dsid,"LABEL") then call symput("label",1);
    rc=close(dsid);
    run;
   %if &misscoef %then %do;
     %put ERROR: Too few contrast coefficients found in CONTRASTS= data set;
     %put ERROR- for estimate set &&set&s (LMatrix=&&set&s) in COEF= data set.;
     %put ERROR- No analysis done for estimate set &&set&s...;
     %goto endset;
   %end;
   %if &miss_set %then %do;
     %put ERROR: No contrast coefficients found in CONTRASTS= data found for;
     %put ERROR- estimate set &&set&s (LMatrix=&&set&s) in COEF= data set.;
     %goto endset;
   %end;
   %if &ratio %then %do;
     %let badcoef=0;
     data _null_;
       set _cntrs;
       badcoef=0; cnt1=0; cntm1=0;
       array k (*) k:;
       do i=1 to dim(k);
         if k(i) not in(-1,0,1,.) then badcoef=1;
         if k(i)=1 then cnt1+1;
         if k(i)=-1 then cntm1+1;
       end;
       if cnt1 ne 1 or cntm1 ne 1 then badcoef=1;
       if badcoef then call symput("badcoef","1");
       run;
     %if &badcoef %then %do;
       %put ERROR: OPTIONS=RATIO requires all contrasts to contain a single 1;
       %put ERROR- for the numerator, a single -1 for the denominator, and;
       %put ERROR- zeros otherwise.;
       %put ERROR: The above message is for estimate set &&set&s...;
       %goto endset;
     %end;
   %end;
%end;

/* Construct fdata= data set for NLEstimate macro */
data _fd;
 if _n_=1 then set _lbt;
 set _cntrs;
 array lb (*) col:;
 array k (*) k:;
 length f $32767;
 %if &label=0 %then length label $32767;;
 do i=1 to dim(lb);
  %if &label=0 %then label=catx(" ",label,k(i));;
  %if &ratio %then %do;
    if k(i)=1 then num=lb(i);
    if k(i)=-1 then den=lb(i);
    f=catx("/",num,den);
  %end;
  %else 
    if k(i) ne 0 then f=catx("+",f,catx("*",k(i),lb(i)));
  ;
 end;
 %if &ratio and &label=0 %then %do;
   negpos=index(label,"-");
   substr(label,negpos,1)="/";
 %end;
 keep label f;
 run;
 
/* Call NLEstimate macro to estimate/test the contrasts */ 
%if &instore ne %then 
  %nlestimate(&dbgopt instore=&instore, fdata=_fd &dfopt &alphaopt 
  &namopt &ttlopt);
%else %if &inest ne and &incovb ne %then 
  %nlestimate(&dbgopt inest=&inest, incovb=&incovb, fdata=_fd &dfopt &alphaopt 
  &namopt &ttlopt);

/* Append results sets if requested or save as separate files */
%if &append %then %do;
  %if %sysfunc(exist(est_all)) and &s=1 %then %do;
    options notes;
    %put NOTE: Data set EST_ALL already exists. Appending to it.;
    %if %index(%upcase(&version),DEBUG)=0 %then options nonotes;;
  %end;
  proc append base=est_all data=est;
  run;
%end;
%else %if &nsets > 1 %then %do;  
  data est&s;
    set est;
    run;
%end;

/* End of processing set of estimates */
  %endset:
%end;

%exit:
  %if %index(%upcase(&version),DEBUG) %then %do;
   options nomprint nomlogic nosymbolgen;
   %put _user_;
  %end;
  %else %do;
    proc datasets nolist nowarn; 
      delete _coef _ct _setnums _nlvl _glognum _glogden _prexp _cntrs _fd _lbt
             _rows _nrows _glg:;
      run; quit;
  %end;  
  ods select all;
  options &notesopt;
  %let timenlm=%sysfunc(round(%sysevalf(%sysfunc(datetime())-&timenlm),0.01));
  %put NOTE: The &sysmacroname macro used &timenlm seconds.;

%mend;

 

This problem has bothered me for a long time, and I hope that there are good people to help me. Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions
StatDave
SAS Super FREQ

As indicated in the NOTE, you should download the latest versions of BOTH macros - NLMeans and NLEST (also known as NLEstimate). The NLMeans macro calls the NLEST macro, so both are needed. See the Download tabs in the documentation of each macro. You can search for and find them at the link in the NOTE, but these links take you directly to each: NLMeans , NLEST. Once downloaded, you need to define them in your active SAS session by submitting a %INC statement for each. As shown in the Usage section of each macro documentation, specify the path to each local file in quotes in the %INC statement. You should then be able to call and use the NLMeans macro.

View solution in original post

3 REPLIES 3
Reeza
Super User

From the log:

 

 NOTE: A newer version of the NLMEANS macro is available at
       this location: http://support.sas.com/
 WARNING: Apparent invocation of macro NLESTIMATE not resolved.
 69             %nlestimate(&dbgopt instore=&instore, fdata=_fd &dfopt &alphaopt    &namopt &ttlopt)
                _
                180
 ERROR 180-322: Statement is not valid or it is used out of proper order.

I would start by fixing those two errors.

StatDave
SAS Super FREQ

As indicated in the NOTE, you should download the latest versions of BOTH macros - NLMeans and NLEST (also known as NLEstimate). The NLMeans macro calls the NLEST macro, so both are needed. See the Download tabs in the documentation of each macro. You can search for and find them at the link in the NOTE, but these links take you directly to each: NLMeans , NLEST. Once downloaded, you need to define them in your active SAS session by submitting a %INC statement for each. As shown in the Usage section of each macro documentation, specify the path to each local file in quotes in the %INC statement. You should then be able to call and use the NLMeans macro.

Lucai_sister
Obsidian | Level 7
The code works fine. Thanks to StatDave!

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 3 replies
  • 1270 views
  • 4 likes
  • 3 in conversation