Tip # 11 -
Solution to NONMEM Coding Challenge #2:
In a previous tip of the week, "Tip of the Week #8 - Sequential
numbering in a NONMEM TABLE" we gave code for generating sequential
ID's (SID), record numbers within an individual (INDR) and
overall sequential record numbers (INDX)):
$PK
;TO SEQUENTIALLY NUMBER
INDIVIDUALS
IF(NEWIND.EQ.0) SID=1
IF(NEWIND.EQ.1) SID=SID+1
;TO NUMBER RECORDS WITHIN
AN INDIVIDUAL
IF(NEWIND.EQ.1.OR.NEWIND.EQ.0) INDR=1
IF(NEWIND.EQ.2) INDR=INDR+1
;TO NUMBER ALL RECORDS
IN A DATAFILE
IF(NEWIND.EQ.0) INDX=1
IF(NEWIND.EQ.1.OR.NEWIND.EQ.2) INDX=INDX+1
...
$ESTIMATION MAXEVAL=9999 PRINT=5 METHOD=0 ;DON'T USE POSTHOC
or FOCE!!!
$TABLE ID TIME DV AMT SID INDR INDX FILE=TABLE.TAB NOPRINT
We also issued the following caveat and challenge - NONMEM
Coding Challenge #2:
Why doesn't this code generate the correct values for
SID & INDX with Posthoc or FOCE?
NONMEM may make more than one "pass" when values from
from the data records are copied for tables and scatterplots.
The reserved variable COMACT is set by NONMEM and may
be tested to determine when NONMEM is making a copying
pass.
COMACT=0: This is not a copying pass.
COMACT=1: This is a copying pass with final thetas; etas
are zero.
COMACT=2: This is a copying pass with final thetas and
conditional etas.
In the case where POSTHOC or FOCE is used, more than
one pass will be made resulting in incorrect values for
SID and INDX in the above code. See NONMEM Users Guide
VIII, pages 133-134 for more information.
How would you code a general method that works for M=0/M=0
Posthoc/M=1?
Send your solutions to nmconsult@globomaxnm.com. Best
solution will appear as a future tip of the week.
The solution to the challenge was suggested by none
other than Professor Beal!
$PK
;
IF (COMACT.EQ.1) THEN ;use this
line for FO
IF (COMACT.EQ.2) THEN ;use this
line for FO POSTHOC or FOCE
;TO SEQUENTIALLY NUMBER
INDIVIDUALS
IF (NEWIND.EQ.0) SID=0
IF (NEWIND.LT.2) SID=SID+1
;TO NUMBER ALL RECORDS
IN A DATAFILE
IF(NEWIND.EQ.0) INDX=1
IF(NEWIND.GT.0) INDX=INDX+1
ENDIF
;TO NUMBER RECORDS
WITHIN AN INDIVIDUAL
IF(NEWIND.LT.2) INDR=1
IF(NEWIND.EQ.2) INDR=INDR+1
...
$EST MAXEVAL=9999 PRINT=5 METHOD=1
$TABLE ID TIME DV AMT SID INDR INDX FILE=TABLE.TAB
NOPRINT