{"id":177,"date":"2020-03-09T22:24:26","date_gmt":"2020-03-09T20:24:26","guid":{"rendered":"http:\/\/jvdl.me\/wordpress\/?p=177"},"modified":"2020-03-10T09:35:03","modified_gmt":"2020-03-10T07:35:03","slug":"nonmem-addl-calculation-in-sas","status":"publish","type":"post","link":"https:\/\/jvdl.me\/blog\/?p=177","title":{"rendered":"NONMEM ADDL Calculation and Compression in SAS"},"content":{"rendered":"\n<p>ADDL represents the number of additional doses that are copies of the current row, with the time since first dose (RTFD) increased at the regular dosing interval (II). This allows for the compression of dose records in the NONMEM dataset. To put it more eloquently:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-style-default is-layout-flow wp-block-quote-is-layout-flow\"><p>The NONMEM data item ADDL on a dose record expresses the number of additional implicit doses that should follow at a regular interval II. In the case where explicit doses exist, ADDL supports compacting them into ADDL\/II notation. <\/p><cite><a href=\"https:\/\/rdrr.io\/rforge\/metrumrg\/man\/addl.html\">https:\/\/rdrr.io\/rforge\/metrumrg\/man\/addl.html<\/a><\/cite><\/blockquote>\n\n\n\n<p>The gist of calculating ADDL is the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Determine an allowed window between doses &#8211; if dosing occurs outside of this window (too soon or too late) the information should not be compressed and the modeller should be aware of it<\/li><li>Group and sort the data by subject ID, treatment, date of exposure, and dose<\/li><li>Assign a sequence number starting from 1 for each treatment (A, B, C, &#8230;) per subject<\/li><li>Determine which doses are &#8220;must-list&#8221;; the first record of every subject should be listed and any exposure attribute changes or exposure delays should be listed<\/li><li>Filter the exposure records to keep only the &#8220;must-list&#8221; data and other data required at the modeller&#8217;s discretion, e.g., the exposure records linked to PK samples<\/li><li>After filtering, the differences in SEQ values are the ADDL values<\/li><\/ul>\n\n\n\n<p>For this example, we will focus on compressing explicit doses and we will stick to date-based dosing only. The principles can be easily adjusted for date-and-time-based exposure data. Instead of defining the dosing interval (II) as 24h, we will just define it as 1 day in a macro variable.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">%let allowed_dose_delay = 1;<\/code><\/pre>\n\n\n\n<p>The exposure data will be defined across two subjects, with multiple treatments, multiple dose levels, and occasional gaps between doses exceeding the 1 day window.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">data ex;\n\tformat date date9.;\n\tinput usubjid trt $ dose date : date9.;\n\tcards;\n1 A 50 01JAN1990\n1 B 75 02JAN1990\n1 A 50 02JAN1990\n1 B 100 03JAN1990\n1 A 50 03JAN1990\n1 B 100 04JAN1990\n1 A 50 05JAN1990\n1 A 100 06JAN1990\n1 B 50 06JAN1990\n1 A 100 07JAN1990\n1 A 100 08JAN1990\n1 A 100 09JAN1990\n2 B 50 01JAN1990\n2 A 75 02JAN1990\n2 B 50 02JAN1990\n2 A 100 03JAN1990\n2 B 50 03JAN1990\n2 B 100 04JAN1990\n2 B 50 05JAN1990\n2 A 100 06JAN1990\n2 B 50 06JAN1990\n2 A 100 07JAN1990\nrun;\n\nproc sort data=ex out=addl_pre;\n\tby usubjid trt date dose;\nrun;<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"337\" height=\"676\" src=\"http:\/\/jvdl.me\/wordpress\/wp-content\/uploads\/2020\/03\/addl_pre-1.png\" alt=\"\" class=\"wp-image-203\" srcset=\"https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl_pre-1.png 337w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl_pre-1-150x300.png 150w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl_pre-1-75x150.png 75w\" sizes=\"auto, (max-width: 337px) 100vw, 337px\" \/><\/figure>\n\n\n\n<p>After the initial dataset has been populated and sorted, a unique sequence number starting from 1 should be assigned to each treatment within each subject. In addition, a &#8220;must_list&#8221; variable will be populated with &#8220;Y&#8221; if:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the first record for the subject is encountered<\/li><li>a new treatment within subject is encountered<\/li><li>the dose level within a treatment was changed<\/li><li>a delay in dosing longer or shorter than the allowed delay window was encountered<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">data addl1;\n\tset addl_pre;\n\tby usubjid trt date dose;\n\n\tretain seq 1;\n\n\tif first.usubjid or first.trt then do;\n\t\tmust_list = \"Y\";\n\t\tseq = 1;\n\tend;\n\telse do;\n\t\tseq + 1;\n\tend;\n\n\tif trt ^= lag(trt) then must_list = \"Y\";\n\tif dose ^= lag(dose) then must_list = \"Y\";\n\tif date - lag(date) ^= &amp;allowed_dose_delay. then must_list = \"Y\";\nrun;<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"500\" height=\"678\" src=\"http:\/\/jvdl.me\/wordpress\/wp-content\/uploads\/2020\/03\/addl1-1.png\" alt=\"\" class=\"wp-image-204\" srcset=\"https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl1-1.png 500w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl1-1-221x300.png 221w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl1-1-111x150.png 111w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/figure>\n\n\n\n<p>The maximum sequence per subject and treatment should be determined to calculate ADDL for the final, must-list exposure records.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">proc sql noprint;\n\tcreate table addl2 as\n\t\tselect *, max(seq) as max_seq\n\t\tfrom addl1\n\t\tgroup by usubjid, trt\n\t\torder by usubjid, trt, date\n\t;\nquit;<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"598\" height=\"676\" src=\"http:\/\/jvdl.me\/wordpress\/wp-content\/uploads\/2020\/03\/addl2-1.png\" alt=\"\" class=\"wp-image-205\" srcset=\"https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl2-1.png 598w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl2-1-265x300.png 265w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl2-1-133x150.png 133w\" sizes=\"auto, (max-width: 598px) 100vw, 598px\" \/><\/figure>\n\n\n\n<p>The exposure events are filtered to keep only the &#8220;must-list&#8221; records. The remaining records will be compressed into the ADDL counter. With real-world data, you may want to add any record linked to PK sampling to the &#8220;must-list&#8221; group. This can be done by linking the exposure date and time with the sample reference dose date and time, e.g., PC.PCRFTDT.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">data addl3;\n\tset addl2(where=(must_list = \"Y\"));\nrun;<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"601\" height=\"387\" src=\"http:\/\/jvdl.me\/wordpress\/wp-content\/uploads\/2020\/03\/addl3-1.png\" alt=\"\" class=\"wp-image-206\" srcset=\"https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl3-1.png 601w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl3-1-300x193.png 300w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl3-1-150x97.png 150w\" sizes=\"auto, (max-width: 601px) 100vw, 601px\" \/><\/figure>\n\n\n\n<p>Reverse sort the dataset to allow peeking at the next sequence records.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">proc sort data=addl3 out=addl4_pre; \n\tby descending usubjid descending trt descending date descending seq;\nrun;\n\ndata addl4;\n\tset addl4_pre;\n\tby descending usubjid descending trt descending date descending seq;\n\n\tnext_seq = lag(seq);\n\tif usubjid ^= lag(usubjid) or trt ^= lag(trt) then next_seq = .;\n\n\tproc sort; by usubjid trt date seq;\nrun;<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"697\" height=\"386\" src=\"http:\/\/jvdl.me\/wordpress\/wp-content\/uploads\/2020\/03\/addl4-1.png\" alt=\"\" class=\"wp-image-207\" srcset=\"https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl4-1.png 697w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl4-1-300x166.png 300w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl4-1-150x83.png 150w\" sizes=\"auto, (max-width: 697px) 100vw, 697px\" \/><\/figure>\n\n\n\n<p>Finally, ADDL is calculated as the difference between MAX_SEQ and SEQ in the case of the final record, otherwise (NEXT_SEQ &#8211; (SEQ + 1)) to ensure we have exclusive bounds between the current and next exposure sequence numbers.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">data addl5;\n\tset addl4;\n\n\tif missing(next_seq) then addl = max_seq - seq;\n\telse addl = next_seq - (seq + 1);\n\n\tkeep usubjid trt date dose addl;\nrun;<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"407\" height=\"386\" src=\"http:\/\/jvdl.me\/wordpress\/wp-content\/uploads\/2020\/03\/addl5-1.png\" alt=\"\" class=\"wp-image-208\" srcset=\"https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl5-1.png 407w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl5-1-300x285.png 300w, https:\/\/jvdl.me\/blog\/wp-content\/uploads\/2020\/03\/addl5-1-150x142.png 150w\" sizes=\"auto, (max-width: 407px) 100vw, 407px\" \/><figcaption>While not explicitly specified here, our data has II defined as 24 hours or 1 day. In real-world data an II column would be visible in the data.<\/figcaption><\/figure>\n\n\n\n<p>Provided that your data is well-structured and clean, compressing the exposure records and calculating ADDL is a straightforward task!  <\/p>\n","protected":false},"excerpt":{"rendered":"<p>ADDL represents the number of additional doses that are copies of the current row, with the time since first dose (RTFD) increased at the regular dosing interval (II). This allows for the compression of dose records in the NONMEM dataset. To put it more eloquently: The NONMEM data item ADDL on a dose record expresses [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[53,54],"tags":[],"class_list":["post-177","post","type-post","status-publish","format-standard","hentry","category-programming","category-sas"],"_links":{"self":[{"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/posts\/177","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=177"}],"version-history":[{"count":18,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/posts\/177\/revisions"}],"predecessor-version":[{"id":210,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/posts\/177\/revisions\/210"}],"wp:attachment":[{"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}