├── .gitattributes ├── .gitignore ├── CDISC_pilot_replication.Rproj ├── LICENSE ├── README.html ├── README.md ├── SessionInfo.txt ├── data └── titles.xlsx ├── outputs ├── 14-1.01.rtf ├── 14-1.02.rtf ├── 14-1.03.rtf ├── 14-2.01.rtf ├── 14-3.01.rtf ├── 14-3.02.rtf ├── 14-3.03.rtf ├── 14-3.04.rtf ├── 14-3.05.rtf ├── 14-3.06.rtf ├── 14-3.07.rtf ├── 14-3.08.rtf ├── 14-3.09.rtf ├── 14-3.10.rtf ├── 14-3.11.rtf ├── 14-3.12.rtf ├── 14-3.13.rtf ├── 14-4.01.rtf ├── 14-5.01.rtf ├── 14-5.02.rtf ├── 14-6.01.rtf ├── 14-6.02.rtf ├── 14-6.03.rtf ├── 14-6.04.rtf ├── 14-6.05.rtf ├── 14-6.06.rtf ├── 14-7.01.rtf ├── 14-7.02.rtf ├── 14-7.03.rtf └── 14-7.04.rtf └── programs ├── config.R ├── funcs.R ├── t-14-1-01.R ├── t-14-1-02.R ├── t-14-1-03.R ├── t-14-2-01.R ├── t-14-3-01.R ├── t-14-3-02.R ├── t-14-3-03.R ├── t-14-3-04.R ├── t-14-3-05.R ├── t-14-3-06.R ├── t-14-3-07.R ├── t-14-3-08.R ├── t-14-3-09.R ├── t-14-3-10.R ├── t-14-3-11.R ├── t-14-3-12.R ├── t-14-3-13.R ├── t-14-4-01.R ├── t-14-5-01.R ├── t-14-5-02.R ├── t-14-6-01.R ├── t-14-6.02.R ├── t-14-6.03.R ├── t-14-6.04.R ├── t-14-6.05.R ├── t-14-6.06.R ├── t-14-7.01.R ├── t-14-7.02.R ├── t-14-7.03.R └── t-14-7.04.R /.gitattributes: -------------------------------------------------------------------------------- 1 | *.rtf linguist-detectable=false 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | /data 6 | -------------------------------------------------------------------------------- /CDISC_pilot_replication.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Atorus Research 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CDISC Pilot Replication in R 2 | 3 | ## Updates 4 | 5 | We've update this repository to be compatible with Huxtable v5.0.0! Huxtable v5.0.0 had some backwards compatibility breaking changes. All updates within this repository are compatible back to Huxtable v4.7.1. See a full list of changes to Huxtable [here](https://hughjonesd.github.io/whats-new-in-huxtable-5.0.0.html). 6 | 7 | The changes most of interest to a user of this repository are: 8 | - The way indexing was handled has changed. You can no longer index columns like `ht[1:5]`. The new syntax is `ht[1:5, ]`. 9 | - Additionally, the `add_columns` argument now changed from a default of `TRUE` instead of `FALSE`. We updated [`config.R`](programs/config.R) to reset the default option to keep the code consistent. You can do this like so: 10 | 11 | ``` 12 | options(huxtable.add_colnames = FALSE) 13 | ``` 14 | 15 | ## Introduction 16 | Welcome to the Atorus CDISC Pilot replication repository! 17 | In 2007, the [original pilot project submission package](https://bitbucket.cdisc.org/projects/CED/repos/sdtm-adam-pilot-project/browse) was finalized and released following a review by FDA Staff, where the CDISC data and metadata contained within the package were evaluated for its suitability in meeting the needs and expectations of medical and statistical reviewers. In 2019, the [PHUSE Test Data Factory](https://advance.phuse.global/display/WEL/Test+Dataset+Factory) took on the goal of replicating the SDTM and ADaM data within the CDISC pilot package to match more modern data standards, bringing the ADaM data up to version 1.1. 18 | Atorus Research has now regenerated the table outputs within the CDISC Pilot Project using the PHUSE Test Data Factory project’s data and the R Programming language. Our motivation behind this project was to: 19 | - Demonstrate that we were able to obtain matching outputs using R 20 | - Provide open source code to the public to demonstrate how we were able to do this 21 | - Demonstrate our first publicly released R package, `pharmaRTF`, in action. 22 | You can find our package pharmaRTF right [here](https://github.com/atorus-research/pharmaRTF) 23 | 24 | ## Setup Instructions 25 | To obtain the data for this repository, you can download the data from the PHUSE Github Repository, using [this link](https://github.com/phuse-org/phuse-scripts/blob/master/data/adam/TDF_ADaM_v1.0.zip) for ADaM data and [this link](https://github.com/phuse-org/phuse-scripts/blob/master/data/sdtm/TDF_SDTM_v1.0%20.zip) 26 | for the SDTM. 27 | 28 | This repository was programmed using R 3.6. For further system information, see our [session information](SessionInfo.txt). 29 | 30 | ## Notes on Data 31 | Every effort was made to use best programming practices to recreate the values on the CDISC Pilot displays, however some values on our outputs do not align with the values on the CDISC Pilot displays due to the following reasons: 32 | 33 | ### General: 34 | - The ADaMs we used to regenerate the CDISC Pilot displays were the PHUSE CDISC Pilot replication ADaMs following ADaM V1.1. Since the CDISC Pilot displays were not regenerated using the PHUSE CDISC Pilot replication data there are likely discrepancies between the original CDISC Pilot analysis data and the PHUSE CDISC Pilot replication ADaMs. 35 | - SAS and R round differently. While SAS rounds up if the value is 5 or greater, R rounds to the nearest even number. 36 | - In some circumstances, R packages will not produce a p-value if the the counts within the data are not high enough to make it statistically meaningful. An example of this is BILIRUBIN on Table 14-6.05. The High at Baseline stratum only has a single count, and the `mantelhein.test` function in R requires that each stratum has more than 1 observation. 37 | 38 | ### Output Specific Details: 39 | - Table 14-3.07 ADAS Cog (11) - Change from Baseline to Week 24 - Completers at Wk 24-Observed Cases-Windowed 40 | - Difference in baseline values. Despite following the analysis results metadata (ARM) in the original CDISC Pilot Define.xml, the baseline counts are off by 1. Following the information available within the original ARM and SAP there is a discrepancy between the available data and the display using both the PHUSE CDISC Pilot replication data and the original CDISC Pilot analysis data. 41 | - Table 14-3.11 ADAS Cog (11) - Repeated Measures Analysis of Change from Baseline to Week 24 42 | - Differences in p-values. See ARM in the original CDISC Pilot Define.xml (ARM-Leaf0046) for details on implementation in SAS. These numbers end up being slightly off. To anyone that finds this and can match the numbers, please feel free to submit a PR and correct our implementation! To the best of our knowledge, we've matched what we could. It's not explicit, but the default covariance structure in the lme4 package in unstructured. 43 | - Table 14-3.12 Mean NPI-X Total Score from Week 4 through Week 24 – Windowed 44 | - Difference in values of Mean of Weeks 4-24. This was programmed using the derived NPTOTMN variable. The ARM in the original CDISC Pilot Define.xml was followed as best as possible to determine the subset. This means that the counts are a discrepancy with the original CDISC Pilot analysis data, which is no longer available, therefore we were not able to investigate the discrepancy with the current PHUSE CDISC Pilot replication data. The subsequent statistical summaries therefore also have differences. 45 | - Table 14-6.05 Shifts of Laboratory Values During Treatment, Categorized Based on Threshold Ranges 46 | - Difference in the values for BILIRUBIN values for the Xan. Low group and MONOCYTES values for the Placebo group. The Analysis Reference Range Indicator and Shift variables are used as is from the ADaM which indicates there are likely discrepancies for reference ranges and shifts between the original CDISC Pilot analysis data and the PHUSE CDISC Pilot replication data. The subsequent statistical summaries therefore also have differences. 47 | - Table 14-6.06 Shifts of Hy's Law Values During Treatment 48 | - Difference in the values for Transaminase 1.5 x ULN for the Xan. Low group and Total Bili 1.5 x ULN and Transaminase 1.5 x ULN for all groups. The Analysis Reference Range Indicator and Shift variables are used as is from the ADaM which indicates there are likely discrepancies for reference ranges and shifts between the original CDISC Pilot analysis data and the PHUSE CDISC Pilot replication data. The subsequent statistical summaries therefore also have differences. 49 | - Table 14-7.01 Summary of Vital Signs at Baseline and End of Treatment 50 | - Difference in values for End of Treatment for all groups. The End of Treatment flag is used as is from the ADaM which indicates there are likely discrepancies for end of treatment between the original CDISC Pilot analysis data and the PHUSE CDISC Pilot replication data. 51 | - Table 14-7.02 Summary of Vital Signs Change from Baseline at End of Treatment 52 | - Difference in values throughout table. The End of Treatment flag is used as is from the ADaM which indicates there are likely discrepancies for end of treatment between the original CDISC Pilot analysis data and the PHUSE CDISC Pilot replication data. 53 | - Table 14-7.03 Summary of Weight Change from Baseline at End of Treatment 54 | - Difference in values for End of Treatment for all groups. The End of Treatment flag is used as is from the ADaM which indicates there are likely discrepancies for end of treatment between the original CDISC Pilot analysis data and the PHUSE CDISC Pilot replication data. 55 | ## Notes on R Packages 56 | As many programmers in the R community do, we relied on the [tidyverse](https://www.tidyverse.org/packages/) for much of our data processing. There are a few addition libraries that we used worth mentioning: 57 | - For the CMH test where testing for the alternate hypothesis that row means differ, the package vcdExtra was used, which is not included in the base distribution of R. We additionally had to make a slight modification to this library, which is available in [this fork]( https://github.com/mstackhouse/vcdExtra) of the package. The update is due to the fact that the `solve` function in R will throw an error when processing large, sparse tables. By replacing `solve` with `MASS::ginv`, the error is bypassed. We as an organization plan to perform further testing of this update and submit the update back to the original author. 58 | - For Mixed Models, the `lme4` package was used 59 | - For ANCOVA models, `car` was used and the `emmeans` package was used to do LSMEANS. 60 | -------------------------------------------------------------------------------- /SessionInfo.txt: -------------------------------------------------------------------------------- 1 | R version 3.6.2 (2019-12-12) 2 | Platform: x86_64-pc-linux-gnu (64-bit) 3 | Running under: Ubuntu 18.04.4 LTS 4 | 5 | Matrix products: default 6 | BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1 7 | LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1 8 | 9 | locale: 10 | [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8 LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8 11 | [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C 12 | 13 | attached base packages: 14 | [1] stats graphics grDevices utils datasets methods base 15 | 16 | other attached packages: 17 | [1] readxl_1.3.1 pharmaRTF_0.1.0 assertthat_0.2.1 haven_2.2.0 forcats_0.4.0 stringr_1.4.0 purrr_0.3.3 readr_1.3.1 18 | [9] tidyr_1.0.2 tibble_2.1.3 ggplot2_3.2.1 tidyverse_1.3.0 glue_1.3.1 dplyr_0.8.4 plyr_1.8.5 19 | 20 | loaded via a namespace (and not attached): 21 | [1] httr_1.4.1 jsonlite_1.6.1 splines_3.6.2 carData_3.0-3 modelr_0.1.5 huxtable_4.7.1 cellranger_1.1.0 22 | [8] pillar_1.4.3 backports_1.1.5 lattice_0.20-38 rvest_0.3.5 minqa_1.2.4 sandwich_2.5-1 colorspace_1.4-1 23 | [15] Matrix_1.2-18 pkgconfig_2.0.3 broom_0.5.4 xtable_1.8-4 mvtnorm_1.1-0 scales_1.1.0 openxlsx_4.1.4 24 | [22] rio_0.5.16 lme4_1.1-21 emmeans_1.4.5 generics_0.0.2 vcdExtra_0.7-4 car_3.0-6 relimp_1.0-5 25 | [29] ellipsis_0.3.0 TH.data_1.0-10 withr_2.1.2 nnet_7.3-12 lazyeval_0.2.2 cli_2.0.1 survival_3.1-8 26 | [36] magrittr_1.5 crayon_1.3.4 estimability_1.3 fs_1.3.1 fansi_0.4.1 nlme_3.1-142 MASS_7.3-51.5 27 | [43] xml2_1.2.2 foreign_0.8-72 gnm_1.1-1 tools_3.6.2 data.table_1.12.8 hms_0.5.3 multcomp_1.4-13 28 | [50] lifecycle_0.1.0 munsell_0.5.0 reprex_0.3.0 zip_2.0.4 packrat_0.5.0 compiler_3.6.2 vcd_1.4-7 29 | [57] ca_0.71.1 rlang_0.4.4 grid_3.6.2 nloptr_1.2.1 rstudioapi_0.10 qvcalc_1.0.2 boot_1.3-23 30 | [64] codetools_0.2-16 gtable_0.3.0 abind_1.4-5 DBI_1.1.0 curl_4.3 R6_2.4.1 zoo_1.8-7 31 | [71] lubridate_1.7.4 knitr_1.28 stringi_1.4.5 Rcpp_1.0.3 vctrs_0.2.2 coda_0.19-3 dbplyr_1.4.2 32 | [78] tidyselect_1.0.0 xfun_0.12 lmtest_0.9-37 -------------------------------------------------------------------------------- /data/titles.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atorus-research/CDISC_pilot_replication/3c8e9e3798c02be8d93bd8e8944d1e0d3f6519e2/data/titles.xlsx -------------------------------------------------------------------------------- /outputs/14-1.01.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff1 2 | {\fonttbl 3 | {\f0 Times;} 4 | {\f1 Courier New;} 5 | }{\colortbl;;} 6 | 7 | 8 | 9 | \paperw15840\paperh12240\widowctrl\ftnbj\fet0\sectd\linex0 10 | \lndscpsxn 11 | \margl1440\margr1440\margt1440\margb1440 12 | \headery720\footery720\fs20 13 | 14 | 15 | 16 | {\header 17 | \ql\tx7245\tqr\tx12960 18 | {\f1\fs20\b\i Protocol: CDISCPILOT01}\pmartabqr 19 | {\f1\fs20\b\i Page }{\f1\fs20\b\i \field\flddirty{\*\fldinst{ PAGE \\* MERGEFORMAT }}}{\f1\fs20\b\i of }{\f1\fs20\b\i \field{\*\fldinst{ NUMPAGES}}} 20 | \par\ql 21 | {\f1\fs20\b\i Population: All Subjects}{\f1\fs20\b\i } 22 | \par\qc 23 | {\f1\fs20\b\i Table 14-1.01}{\f1\fs20\b\i } 24 | \par\qc 25 | {\f1\fs20\b\i Summary of Populations}{\f1\fs20\b\i } 26 | \par 27 | 28 | { 29 | \trowd 30 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx3802 31 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5228 32 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6653 33 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8079 34 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx9504 \pard\intbl\ql{\fs20 {}}\cell 35 | \pard\intbl\ql{\fs20 {}}\cell 36 | \pard\intbl\ql{\fs20 {}}\cell 37 | \pard\intbl\ql{\fs20 {}}\cell 38 | \pard\intbl\ql{\fs20 {}}\cell 39 | \row 40 | } 41 | 42 | { 43 | \trowd 44 | \trqc \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx3802 45 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5228 46 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6653 47 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8079 48 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx9504 \pard\intbl\qc{\fs20 \b {}\b0}\cell 49 | \pard\intbl\qc{\fs20 \b {Placebo\line (N=86)}\b0}\cell 50 | \pard\intbl\qc{\fs20 \b {Xanomeline\line Low Dose\line (N=84)}\b0}\cell 51 | \pard\intbl\qc{\fs20 \b {Xanomeline\line High Dose\line (N=84)}\b0}\cell 52 | \pard\intbl\qc{\fs20 \b {Total\line (N=254)}\b0}\cell 53 | \row 54 | } 55 | 56 | } 57 | {\footer 58 | \ql 59 | {\f1\fs20\i NOTE: N in column headers represents number of subjects entered in study (i.e., signed informed consent). The ITT population includes all subjects randomized. The Safety population includes all randomized subjects known to have taken at least one dose of randomized study drug. The Efficacy population includes all subjects in the safety population who also have at least one post-baseline ADAS-Cog and CIBIC+ assessment.}{\f1\fs20\i } 60 | \par\ql\tx7245\tqr\tx12960 61 | {\f1\fs20\i Source: programs/t-14-1-01.R}\pmartabqr 62 | {\f1\fs20\i 19:24 Tuesday, June 16, 2020}\par 63 | } 64 | { 65 | \trowd 66 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx3802 67 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5228 68 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6653 69 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8079 70 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx9504 \pard\intbl\ql{Intent-To-Treat (ITT)}\cell 71 | \pard\intbl\ql{ 86 (100%)}\cell 72 | \pard\intbl\ql{ 84 (100%)}\cell 73 | \pard\intbl\ql{ 84 (100%)}\cell 74 | \pard\intbl\ql{254 (100%)}\cell 75 | \row 76 | } 77 | 78 | { 79 | \trowd 80 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx3802 81 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5228 82 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6653 83 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8079 84 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx9504 \pard\intbl\ql{Safety}\cell 85 | \pard\intbl\ql{ 86 (100%)}\cell 86 | \pard\intbl\ql{ 84 (100%)}\cell 87 | \pard\intbl\ql{ 84 (100%)}\cell 88 | \pard\intbl\ql{254 (100%)}\cell 89 | \row 90 | } 91 | 92 | { 93 | \trowd 94 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx3802 95 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5228 96 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6653 97 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8079 98 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx9504 \pard\intbl\ql{Efficacy}\cell 99 | \pard\intbl\ql{ 79 ( 92%)}\cell 100 | \pard\intbl\ql{ 81 ( 96%)}\cell 101 | \pard\intbl\ql{ 74 ( 88%)}\cell 102 | \pard\intbl\ql{234 ( 92%)}\cell 103 | \row 104 | } 105 | 106 | { 107 | \trowd 108 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx3802 109 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5228 110 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6653 111 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8079 112 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx9504 \pard\intbl\ql{Complete Week 24}\cell 113 | \pard\intbl\ql{ 60 ( 70%)}\cell 114 | \pard\intbl\ql{ 28 ( 33%)}\cell 115 | \pard\intbl\ql{ 30 ( 36%)}\cell 116 | \pard\intbl\ql{118 ( 46%)}\cell 117 | \row 118 | } 119 | 120 | { 121 | \trowd 122 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx3802 123 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5228 124 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6653 125 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8079 126 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx9504 \pard\intbl\ql{Complete Study}\cell 127 | \pard\intbl\ql{ 58 ( 67%)}\cell 128 | \pard\intbl\ql{ 25 ( 30%)}\cell 129 | \pard\intbl\ql{ 27 ( 32%)}\cell 130 | \pard\intbl\ql{110 ( 43%)}\cell 131 | \row 132 | } 133 | 134 | } -------------------------------------------------------------------------------- /outputs/14-3.02.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff1 2 | {\fonttbl 3 | {\f0 Times;} 4 | {\f1 Courier New;} 5 | }{\colortbl;;} 6 | 7 | 8 | 9 | \paperw15840\paperh12240\widowctrl\ftnbj\fet0\sectd\linex0 10 | \lndscpsxn 11 | \margl1440\margr1440\margt1440\margb1440 12 | \headery720\footery720\fs20 13 | 14 | 15 | 16 | {\header 17 | \ql\tx7245\tqr\tx12960 18 | {\f1\fs20\b\i Protocol: CDISCPILOT01}\pmartabqr 19 | {\f1\fs20\b\i Page }{\f1\fs20\b\i \field\flddirty{\*\fldinst{ PAGE \\* MERGEFORMAT }}}{\f1\fs20\b\i of }{\f1\fs20\b\i \field{\*\fldinst{ NUMPAGES}}} 20 | \par\ql 21 | {\f1\fs20\b\i Population: Efficacy}{\f1\fs20\b\i } 22 | \par\qc 23 | {\f1\fs20\b\i Table 14-3.02}{\f1\fs20\b\i } 24 | \par\qc 25 | {\f1\fs20\b\i Primary Endpoint Analysis: CIBIC+ - Summary at Week 24 - LOCF}{\f1\fs20\b\i } 26 | \par 27 | 28 | { 29 | \trowd 30 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 31 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 32 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 33 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{\fs20 {}}\cell 34 | \pard\intbl\ql{\fs20 {}}\cell 35 | \pard\intbl\ql{\fs20 {}}\cell 36 | \pard\intbl\ql{\fs20 {}}\cell 37 | \row 38 | } 39 | 40 | { 41 | \trowd 42 | \trqc \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 43 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 44 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 45 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\qc{\fs20 \b {}\b0}\cell 46 | \pard\intbl\qc{\fs20 \b {Placebo\line (N=79)}\b0}\cell 47 | \pard\intbl\qc{\fs20 \b {Xanomeline\line Low Dose\line (N=81)}\b0}\cell 48 | \pard\intbl\qc{\fs20 \b {Xanomeline\line High Dose\line (N=74)}\b0}\cell 49 | \row 50 | } 51 | 52 | } 53 | {\footer 54 | \ql 55 | {\f1\fs20\i [1] Based on Analysis of covariance (ANCOVA) model with treatment and site group as factors.}{\f1\fs20\i } 56 | \par\ql 57 | {\f1\fs20\i [2] Test for a non-zero coefficient for treatment (dose) as a continuous variable.}{\f1\fs20\i } 58 | \par\ql 59 | {\f1\fs20\i [3] Pairwise comparison with treatment as a categorical variable: p-values without adjustment for multiple comparisons.}{\f1\fs20\i } 60 | \par\ql\tx7245\tqr\tx12960 61 | {\f1\fs20\i Source: programs/t-14-3-02.R}\pmartabqr 62 | {\f1\fs20\i 19:26 Tuesday, June 16, 2020}\par 63 | } 64 | { 65 | \trowd 66 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 67 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 68 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 69 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{Week 24}\cell 70 | \pard\intbl\ql{}\cell 71 | \pard\intbl\ql{}\cell 72 | \pard\intbl\ql{}\cell 73 | \row 74 | } 75 | 76 | { 77 | \trowd 78 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 79 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 80 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 81 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ n}\cell 82 | \pard\intbl\ql{79 }\cell 83 | \pard\intbl\ql{81 }\cell 84 | \pard\intbl\ql{74 }\cell 85 | \row 86 | } 87 | 88 | { 89 | \trowd 90 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 91 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 92 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 93 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Mean (SD)}\cell 94 | \pard\intbl\ql{ 4.3 ( 0.77)}\cell 95 | \pard\intbl\ql{ 4.2 ( 0.79)}\cell 96 | \pard\intbl\ql{ 4.3 ( 0.81)}\cell 97 | \row 98 | } 99 | 100 | { 101 | \trowd 102 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 103 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 104 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 105 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Median (Range)}\cell 106 | \pard\intbl\ql{ 4.0 ( 2; 6)}\cell 107 | \pard\intbl\ql{ 4.0 ( 2; 6)}\cell 108 | \pard\intbl\ql{ 4.0 ( 3; 6)}\cell 109 | \row 110 | } 111 | 112 | { 113 | \trowd 114 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 115 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 116 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 117 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 118 | \pard\intbl\ql{}\cell 119 | \pard\intbl\ql{}\cell 120 | \pard\intbl\ql{}\cell 121 | \row 122 | } 123 | 124 | { 125 | \trowd 126 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 127 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 128 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 129 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Dose Response) [1][2]}\cell 130 | \pard\intbl\ql{}\cell 131 | \pard\intbl\ql{}\cell 132 | \pard\intbl\ql{ 0.960 }\cell 133 | \row 134 | } 135 | 136 | { 137 | \trowd 138 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 139 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 140 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 141 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 142 | \pard\intbl\ql{}\cell 143 | \pard\intbl\ql{}\cell 144 | \pard\intbl\ql{}\cell 145 | \row 146 | } 147 | 148 | { 149 | \trowd 150 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 151 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 152 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 153 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Xan - Placebo) [1][3]}\cell 154 | \pard\intbl\ql{}\cell 155 | \pard\intbl\ql{ 0.489 }\cell 156 | \pard\intbl\ql{ 0.799 }\cell 157 | \row 158 | } 159 | 160 | { 161 | \trowd 162 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 163 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 164 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 165 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Diff of LS Means (SE)}\cell 166 | \pard\intbl\ql{}\cell 167 | \pard\intbl\ql{-0.1 (0.13)}\cell 168 | \pard\intbl\ql{ 0.0 (0.13)}\cell 169 | \row 170 | } 171 | 172 | { 173 | \trowd 174 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 175 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 176 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 177 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ 95% CI}\cell 178 | \pard\intbl\ql{}\cell 179 | \pard\intbl\ql{(-0.3;0.2)}\cell 180 | \pard\intbl\ql{(-0.2;0.3)}\cell 181 | \row 182 | } 183 | 184 | { 185 | \trowd 186 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 187 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 188 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 189 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 190 | \pard\intbl\ql{}\cell 191 | \pard\intbl\ql{}\cell 192 | \pard\intbl\ql{}\cell 193 | \row 194 | } 195 | 196 | { 197 | \trowd 198 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 199 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 200 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 201 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Xan High - Xan Low) [1][3]}\cell 202 | \pard\intbl\ql{}\cell 203 | \pard\intbl\ql{}\cell 204 | \pard\intbl\ql{ 0.349 }\cell 205 | \row 206 | } 207 | 208 | { 209 | \trowd 210 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 211 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 212 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 213 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Diff of LS Means (SE)}\cell 214 | \pard\intbl\ql{}\cell 215 | \pard\intbl\ql{}\cell 216 | \pard\intbl\ql{ 0.1 (0.13)}\cell 217 | \row 218 | } 219 | 220 | { 221 | \trowd 222 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 223 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 224 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 225 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ 95% CI}\cell 226 | \pard\intbl\ql{}\cell 227 | \pard\intbl\ql{}\cell 228 | \pard\intbl\ql{(-0.1;0.4)}\cell 229 | \row 230 | } 231 | 232 | } -------------------------------------------------------------------------------- /outputs/14-3.04.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff1 2 | {\fonttbl 3 | {\f0 Times;} 4 | {\f1 Courier New;} 5 | }{\colortbl;;} 6 | 7 | 8 | 9 | \paperw15840\paperh12240\widowctrl\ftnbj\fet0\sectd\linex0 10 | \lndscpsxn 11 | \margl1440\margr1440\margt1440\margb1440 12 | \headery720\footery720\fs20 13 | 14 | 15 | 16 | {\header 17 | \ql\tx7245\tqr\tx12960 18 | {\f1\fs20\b\i Protocol: CDISCPILOT01}\pmartabqr 19 | {\f1\fs20\b\i Page }{\f1\fs20\b\i \field\flddirty{\*\fldinst{ PAGE \\* MERGEFORMAT }}}{\f1\fs20\b\i of }{\f1\fs20\b\i \field{\*\fldinst{ NUMPAGES}}} 20 | \par\ql 21 | {\f1\fs20\b\i Population: Efficacy}{\f1\fs20\b\i } 22 | \par\qc 23 | {\f1\fs20\b\i Table 14-3.04}{\f1\fs20\b\i } 24 | \par\qc 25 | {\f1\fs20\b\i CIBIC+ - Summary at Week 8 - LOCF}{\f1\fs20\b\i } 26 | \par 27 | 28 | { 29 | \trowd 30 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 31 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 32 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 33 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{\fs20 {}}\cell 34 | \pard\intbl\ql{\fs20 {}}\cell 35 | \pard\intbl\ql{\fs20 {}}\cell 36 | \pard\intbl\ql{\fs20 {}}\cell 37 | \row 38 | } 39 | 40 | { 41 | \trowd 42 | \trqc \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 43 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 44 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 45 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\qc{\fs20 \b {}\b0}\cell 46 | \pard\intbl\qc{\fs20 \b {Placebo\line (N=79)}\b0}\cell 47 | \pard\intbl\qc{\fs20 \b {Xanomeline\line Low Dose\line (N=81)}\b0}\cell 48 | \pard\intbl\qc{\fs20 \b {Xanomeline\line High Dose\line (N=74)}\b0}\cell 49 | \row 50 | } 51 | 52 | } 53 | {\footer 54 | \ql 55 | {\f1\fs20\i [1] Based on Analysis of covariance (ANCOVA) model with treatment and site group as factors.}{\f1\fs20\i } 56 | \par\ql 57 | {\f1\fs20\i [2] Test for a non-zero coefficient for treatment (dose) as a continuous variable.}{\f1\fs20\i } 58 | \par\ql 59 | {\f1\fs20\i [3] Pairwise comparison with treatment as a categorical variable: p-values without adjustment for multiple comparisons.}{\f1\fs20\i } 60 | \par\ql\tx7245\tqr\tx12960 61 | {\f1\fs20\i Source: programs/t-14-3-04.R}\pmartabqr 62 | {\f1\fs20\i 19:26 Tuesday, June 16, 2020}\par 63 | } 64 | { 65 | \trowd 66 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 67 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 68 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 69 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{Week 8}\cell 70 | \pard\intbl\ql{}\cell 71 | \pard\intbl\ql{}\cell 72 | \pard\intbl\ql{}\cell 73 | \row 74 | } 75 | 76 | { 77 | \trowd 78 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 79 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 80 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 81 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ n}\cell 82 | \pard\intbl\ql{77 }\cell 83 | \pard\intbl\ql{81 }\cell 84 | \pard\intbl\ql{73 }\cell 85 | \row 86 | } 87 | 88 | { 89 | \trowd 90 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 91 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 92 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 93 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Mean (SD)}\cell 94 | \pard\intbl\ql{ 3.9 ( 0.73)}\cell 95 | \pard\intbl\ql{ 4.0 ( 0.72)}\cell 96 | \pard\intbl\ql{ 4.1 ( 0.75)}\cell 97 | \row 98 | } 99 | 100 | { 101 | \trowd 102 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 103 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 104 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 105 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Median (Range)}\cell 106 | \pard\intbl\ql{ 4.0 ( 2; 6)}\cell 107 | \pard\intbl\ql{ 4.0 ( 2; 6)}\cell 108 | \pard\intbl\ql{ 4.0 ( 2; 6)}\cell 109 | \row 110 | } 111 | 112 | { 113 | \trowd 114 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 115 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 116 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 117 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 118 | \pard\intbl\ql{}\cell 119 | \pard\intbl\ql{}\cell 120 | \pard\intbl\ql{}\cell 121 | \row 122 | } 123 | 124 | { 125 | \trowd 126 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 127 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 128 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 129 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Dose Response) [1][2]}\cell 130 | \pard\intbl\ql{}\cell 131 | \pard\intbl\ql{}\cell 132 | \pard\intbl\ql{ 0.167 }\cell 133 | \row 134 | } 135 | 136 | { 137 | \trowd 138 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 139 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 140 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 141 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 142 | \pard\intbl\ql{}\cell 143 | \pard\intbl\ql{}\cell 144 | \pard\intbl\ql{}\cell 145 | \row 146 | } 147 | 148 | { 149 | \trowd 150 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 151 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 152 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 153 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Xan - Placebo) [1][3]}\cell 154 | \pard\intbl\ql{}\cell 155 | \pard\intbl\ql{ 0.754 }\cell 156 | \pard\intbl\ql{ 0.128 }\cell 157 | \row 158 | } 159 | 160 | { 161 | \trowd 162 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 163 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 164 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 165 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Diff of LS Means (SE)}\cell 166 | \pard\intbl\ql{}\cell 167 | \pard\intbl\ql{ 0.0 (0.12)}\cell 168 | \pard\intbl\ql{ 0.2 (0.12)}\cell 169 | \row 170 | } 171 | 172 | { 173 | \trowd 174 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 175 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 176 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 177 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ 95% CI}\cell 178 | \pard\intbl\ql{}\cell 179 | \pard\intbl\ql{(-0.2;0.3)}\cell 180 | \pard\intbl\ql{(-0.1;0.4)}\cell 181 | \row 182 | } 183 | 184 | { 185 | \trowd 186 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 187 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 188 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 189 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 190 | \pard\intbl\ql{}\cell 191 | \pard\intbl\ql{}\cell 192 | \pard\intbl\ql{}\cell 193 | \row 194 | } 195 | 196 | { 197 | \trowd 198 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 199 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 200 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 201 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Xan High - Xan Low) [1][3]}\cell 202 | \pard\intbl\ql{}\cell 203 | \pard\intbl\ql{}\cell 204 | \pard\intbl\ql{ 0.218 }\cell 205 | \row 206 | } 207 | 208 | { 209 | \trowd 210 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 211 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 212 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 213 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Diff of LS Means (SE)}\cell 214 | \pard\intbl\ql{}\cell 215 | \pard\intbl\ql{}\cell 216 | \pard\intbl\ql{ 0.1 (0.12)}\cell 217 | \row 218 | } 219 | 220 | { 221 | \trowd 222 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 223 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 224 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 225 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ 95% CI}\cell 226 | \pard\intbl\ql{}\cell 227 | \pard\intbl\ql{}\cell 228 | \pard\intbl\ql{(-0.1;0.4)}\cell 229 | \row 230 | } 231 | 232 | } -------------------------------------------------------------------------------- /outputs/14-3.06.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff1 2 | {\fonttbl 3 | {\f0 Times;} 4 | {\f1 Courier New;} 5 | }{\colortbl;;} 6 | 7 | 8 | 9 | \paperw15840\paperh12240\widowctrl\ftnbj\fet0\sectd\linex0 10 | \lndscpsxn 11 | \margl1440\margr1440\margt1440\margb1440 12 | \headery720\footery720\fs20 13 | 14 | 15 | 16 | {\header 17 | \ql\tx7245\tqr\tx12960 18 | {\f1\fs20\b\i Protocol: CDISCPILOT01}\pmartabqr 19 | {\f1\fs20\b\i Page }{\f1\fs20\b\i \field\flddirty{\*\fldinst{ PAGE \\* MERGEFORMAT }}}{\f1\fs20\b\i of }{\f1\fs20\b\i \field{\*\fldinst{ NUMPAGES}}} 20 | \par\ql 21 | {\f1\fs20\b\i Population: Efficacy}{\f1\fs20\b\i } 22 | \par\qc 23 | {\f1\fs20\b\i Table 14-3.06}{\f1\fs20\b\i } 24 | \par\qc 25 | {\f1\fs20\b\i CIBIC+ - Summary at Week 16 - LOCF}{\f1\fs20\b\i } 26 | \par 27 | 28 | { 29 | \trowd 30 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 31 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 32 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 33 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{\fs20 {}}\cell 34 | \pard\intbl\ql{\fs20 {}}\cell 35 | \pard\intbl\ql{\fs20 {}}\cell 36 | \pard\intbl\ql{\fs20 {}}\cell 37 | \row 38 | } 39 | 40 | { 41 | \trowd 42 | \trqc \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 43 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 44 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 45 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\qc{\fs20 \b {}\b0}\cell 46 | \pard\intbl\qc{\fs20 \b {Placebo\line (N=79)}\b0}\cell 47 | \pard\intbl\qc{\fs20 \b {Xanomeline\line Low Dose\line (N=81)}\b0}\cell 48 | \pard\intbl\qc{\fs20 \b {Xanomeline\line High Dose\line (N=74)}\b0}\cell 49 | \row 50 | } 51 | 52 | } 53 | {\footer 54 | \ql 55 | {\f1\fs20\i [1] Based on Analysis of covariance (ANCOVA) model with treatment and site group as factors.}{\f1\fs20\i } 56 | \par\ql 57 | {\f1\fs20\i [2] Test for a non-zero coefficient for treatment (dose) as a continuous variable.}{\f1\fs20\i } 58 | \par\ql 59 | {\f1\fs20\i [3] Pairwise comparison with treatment as a categorical variable: p-values without adjustment for multiple comparisons.}{\f1\fs20\i } 60 | \par\ql\tx7245\tqr\tx12960 61 | {\f1\fs20\i Source: programs/t-14-3-06.R}\pmartabqr 62 | {\f1\fs20\i 19:26 Tuesday, June 16, 2020}\par 63 | } 64 | { 65 | \trowd 66 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 67 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 68 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 69 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{Week 16}\cell 70 | \pard\intbl\ql{}\cell 71 | \pard\intbl\ql{}\cell 72 | \pard\intbl\ql{}\cell 73 | \row 74 | } 75 | 76 | { 77 | \trowd 78 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 79 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 80 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 81 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ n}\cell 82 | \pard\intbl\ql{79 }\cell 83 | \pard\intbl\ql{81 }\cell 84 | \pard\intbl\ql{74 }\cell 85 | \row 86 | } 87 | 88 | { 89 | \trowd 90 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 91 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 92 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 93 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Mean (SD)}\cell 94 | \pard\intbl\ql{ 4.2 ( 0.70)}\cell 95 | \pard\intbl\ql{ 4.0 ( 0.77)}\cell 96 | \pard\intbl\ql{ 4.0 ( 0.75)}\cell 97 | \row 98 | } 99 | 100 | { 101 | \trowd 102 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 103 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 104 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 105 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Median (Range)}\cell 106 | \pard\intbl\ql{ 4.0 ( 3; 6)}\cell 107 | \pard\intbl\ql{ 4.0 ( 2; 6)}\cell 108 | \pard\intbl\ql{ 4.0 ( 2; 5)}\cell 109 | \row 110 | } 111 | 112 | { 113 | \trowd 114 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 115 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 116 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 117 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 118 | \pard\intbl\ql{}\cell 119 | \pard\intbl\ql{}\cell 120 | \pard\intbl\ql{}\cell 121 | \row 122 | } 123 | 124 | { 125 | \trowd 126 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 127 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 128 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 129 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Dose Response) [1][2]}\cell 130 | \pard\intbl\ql{}\cell 131 | \pard\intbl\ql{}\cell 132 | \pard\intbl\ql{ 0.214 }\cell 133 | \row 134 | } 135 | 136 | { 137 | \trowd 138 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 139 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 140 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 141 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 142 | \pard\intbl\ql{}\cell 143 | \pard\intbl\ql{}\cell 144 | \pard\intbl\ql{}\cell 145 | \row 146 | } 147 | 148 | { 149 | \trowd 150 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 151 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 152 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 153 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Xan - Placebo) [1][3]}\cell 154 | \pard\intbl\ql{}\cell 155 | \pard\intbl\ql{ 0.219 }\cell 156 | \pard\intbl\ql{ 0.272 }\cell 157 | \row 158 | } 159 | 160 | { 161 | \trowd 162 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 163 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 164 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 165 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Diff of LS Means (SE)}\cell 166 | \pard\intbl\ql{}\cell 167 | \pard\intbl\ql{-0.1 (0.12)}\cell 168 | \pard\intbl\ql{-0.1 (0.12)}\cell 169 | \row 170 | } 171 | 172 | { 173 | \trowd 174 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 175 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 176 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 177 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ 95% CI}\cell 178 | \pard\intbl\ql{}\cell 179 | \pard\intbl\ql{(-0.4;0.1)}\cell 180 | \pard\intbl\ql{(-0.4;0.1)}\cell 181 | \row 182 | } 183 | 184 | { 185 | \trowd 186 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 187 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 188 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 189 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 190 | \pard\intbl\ql{}\cell 191 | \pard\intbl\ql{}\cell 192 | \pard\intbl\ql{}\cell 193 | \row 194 | } 195 | 196 | { 197 | \trowd 198 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 199 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 200 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 201 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Xan High - Xan Low) [1][3]}\cell 202 | \pard\intbl\ql{}\cell 203 | \pard\intbl\ql{}\cell 204 | \pard\intbl\ql{ 0.916 }\cell 205 | \row 206 | } 207 | 208 | { 209 | \trowd 210 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 211 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 212 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 213 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Diff of LS Means (SE)}\cell 214 | \pard\intbl\ql{}\cell 215 | \pard\intbl\ql{}\cell 216 | \pard\intbl\ql{ 0.0 (0.12)}\cell 217 | \row 218 | } 219 | 220 | { 221 | \trowd 222 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 223 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 224 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 225 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ 95% CI}\cell 226 | \pard\intbl\ql{}\cell 227 | \pard\intbl\ql{}\cell 228 | \pard\intbl\ql{(-0.2;0.2)}\cell 229 | \row 230 | } 231 | 232 | } -------------------------------------------------------------------------------- /outputs/14-3.11.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff1 2 | {\fonttbl 3 | {\f0 Times;} 4 | {\f1 Courier New;} 5 | }{\colortbl;;} 6 | 7 | 8 | 9 | \paperw15840\paperh12240\widowctrl\ftnbj\fet0\sectd\linex0 10 | \lndscpsxn 11 | \margl1440\margr1440\margt1440\margb1440 12 | \headery720\footery720\fs20 13 | 14 | 15 | 16 | {\header 17 | \ql\tx7245\tqr\tx12960 18 | {\f1\fs20\b\i Protocol: CDISCPILOT01}\pmartabqr 19 | {\f1\fs20\b\i Page }{\f1\fs20\b\i \field\flddirty{\*\fldinst{ PAGE \\* MERGEFORMAT }}}{\f1\fs20\b\i of }{\f1\fs20\b\i \field{\*\fldinst{ NUMPAGES}}} 20 | \par\ql 21 | {\f1\fs20\b\i Population: Efficacy}{\f1\fs20\b\i } 22 | \par\qc 23 | {\f1\fs20\b\i Table 14-3.11}{\f1\fs20\b\i } 24 | \par\qc 25 | {\f1\fs20\b\i ADAS Cog (11) - Repeated Measures Analysis of Change from Baseline to Week 24}{\f1\fs20\b\i } 26 | \par 27 | 28 | { 29 | \trowd 30 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 31 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 32 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 33 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{\fs20 {}}\cell 34 | \pard\intbl\ql{\fs20 {}}\cell 35 | \pard\intbl\ql{\fs20 {}}\cell 36 | \pard\intbl\ql{\fs20 {}}\cell 37 | \row 38 | } 39 | 40 | { 41 | \trowd 42 | \trqc \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 43 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 44 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 45 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\qc{\fs20 \b {}\b0}\cell 46 | \pard\intbl\qc{\fs20 \b {Placebo\line (N=79)}\b0}\cell 47 | \pard\intbl\qc{\fs20 \b {Xanomeline\line Low Dose\line (N=81)}\b0}\cell 48 | \pard\intbl\qc{\fs20 \b {Xanomeline\line High Dose\line (N=74)}\b0}\cell 49 | \row 50 | } 51 | 52 | } 53 | {\footer 54 | \ql 55 | {\f1\fs20\i Note: The change from baseline is calculated as the post-baseline score minus the baseline score. The covariates included in the MMRM model are treatment, site group, time and treatment by time interaction, baseline ADAS-Cog (11) score, and baseline ADAS-Cog (11) score by time interaction.}{\f1\fs20\i } 56 | \par\ql\tx7245\tqr\tx12960 57 | {\f1\fs20\i Source: programs/t-14-3-11.R}\pmartabqr 58 | {\f1\fs20\i 19:28 Tuesday, June 16, 2020}\par 59 | } 60 | { 61 | \trowd 62 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 63 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 64 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 65 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{LS Means (SE)}\cell 66 | \pard\intbl\ql{1.5 (0.49)}\cell 67 | \pard\intbl\ql{1.5 (0.52)}\cell 68 | \pard\intbl\ql{1.1 (0.55)}\cell 69 | \row 70 | } 71 | 72 | { 73 | \trowd 74 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 75 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 76 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 77 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 78 | \pard\intbl\ql{}\cell 79 | \pard\intbl\ql{}\cell 80 | \pard\intbl\ql{}\cell 81 | \row 82 | } 83 | 84 | { 85 | \trowd 86 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 87 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 88 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 89 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Xan - Placebo)}\cell 90 | \pard\intbl\ql{}\cell 91 | \pard\intbl\ql{ 0.965 }\cell 92 | \pard\intbl\ql{ 0.546 }\cell 93 | \row 94 | } 95 | 96 | { 97 | \trowd 98 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 99 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 100 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 101 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Diff of LS Means (SE)}\cell 102 | \pard\intbl\ql{}\cell 103 | \pard\intbl\ql{ 0.0 (0.69)}\cell 104 | \pard\intbl\ql{-0.4 (0.72)}\cell 105 | \row 106 | } 107 | 108 | { 109 | \trowd 110 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 111 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 112 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 113 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ 95% CI}\cell 114 | \pard\intbl\ql{}\cell 115 | \pard\intbl\ql{(-1.4;1.3)}\cell 116 | \pard\intbl\ql{(-1.9;1.0)}\cell 117 | \row 118 | } 119 | 120 | { 121 | \trowd 122 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 123 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 124 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 125 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{}\cell 126 | \pard\intbl\ql{}\cell 127 | \pard\intbl\ql{}\cell 128 | \pard\intbl\ql{}\cell 129 | \row 130 | } 131 | 132 | { 133 | \trowd 134 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 135 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 136 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 137 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{p-value(Xan High - Xan Low)}\cell 138 | \pard\intbl\ql{}\cell 139 | \pard\intbl\ql{}\cell 140 | \pard\intbl\ql{ 0.588 }\cell 141 | \row 142 | } 143 | 144 | { 145 | \trowd 146 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 147 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 148 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 149 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ Diff of LS Means (SE)}\cell 150 | \pard\intbl\ql{}\cell 151 | \pard\intbl\ql{}\cell 152 | \pard\intbl\ql{-0.4 (0.74)}\cell 153 | \row 154 | } 155 | 156 | { 157 | \trowd 158 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 159 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6912 160 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8640 161 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10368 \pard\intbl\ql{ 95% CI}\cell 162 | \pard\intbl\ql{}\cell 163 | \pard\intbl\ql{}\cell 164 | \pard\intbl\ql{(-1.9;1.1)}\cell 165 | \row 166 | } 167 | 168 | } -------------------------------------------------------------------------------- /outputs/14-5.02.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff1 2 | {\fonttbl 3 | {\f0 Times;} 4 | {\f1 Courier New;} 5 | }{\colortbl;;} 6 | 7 | 8 | 9 | \paperw15840\paperh12240\widowctrl\ftnbj\fet0\sectd\linex0 10 | \lndscpsxn 11 | \margl1440\margr1440\margt1440\margb1440 12 | \headery720\footery720\fs20 13 | 14 | 15 | 16 | {\header 17 | \ql\tx7245\tqr\tx12960 18 | {\f1\fs20\b\i Protocol: CDISCPILOT01}\pmartabqr 19 | {\f1\fs20\b\i Page }{\f1\fs20\b\i \field\flddirty{\*\fldinst{ PAGE \\* MERGEFORMAT }}}{\f1\fs20\b\i of }{\f1\fs20\b\i \field{\*\fldinst{ NUMPAGES}}} 20 | \par\ql 21 | {\f1\fs20\b\i Population: Safety}{\f1\fs20\b\i } 22 | \par\qc 23 | {\f1\fs20\b\i Table 14-5.02}{\f1\fs20\b\i } 24 | \par\qc 25 | {\f1\fs20\b\i Incidence of Treatment Emergent Serious Adverse Events by Treatment Group}{\f1\fs20\b\i } 26 | \par 27 | 28 | { 29 | \trowd 30 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx3888 31 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx5184 32 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx6092 33 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx7388 34 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx8295 35 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx9591 36 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx10498 37 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx11664 38 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt80 \clpadfb0\clpadb80 \clpadfr0\clpadr80 \cellx12960 \pard\intbl\ql{\fs20 {}}\cell 39 | \pard\intbl\ql{\fs20 {}}\cell 40 | \pard\intbl\ql{\fs20 {}}\cell 41 | \pard\intbl\ql{\fs20 {}}\cell 42 | \pard\intbl\ql{\fs20 {}}\cell 43 | \pard\intbl\ql{\fs20 {}}\cell 44 | \pard\intbl\ql{\fs20 {}}\cell 45 | \pard\intbl\ql{\fs20 {}}\cell 46 | \pard\intbl\ql{\fs20 {}}\cell 47 | \row 48 | } 49 | 50 | { 51 | \trowd 52 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx3888 53 | \clmgf\clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx5184 54 | \clmrg\clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx6092 55 | \clmgf\clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx7388 56 | \clmrg\clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx8295 57 | \clmgf\clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx9591 58 | \clmrg\clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx10498 59 | \clmgf\clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx11664 60 | \clmrg\clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx12960 \pard\intbl\qc{\fs20 \b {}\b0}\cell 61 | \pard\intbl\qc{\fs20 \b {Placebo\line (N=86)}\b0}\cell 62 | \pard\intbl\qc{\fs20 \b {}\b0}\cell 63 | \pard\intbl\qc{\fs20 \b {Xanomeline\line Low Dose\line (N=84)}\b0}\cell 64 | \pard\intbl\qc{\fs20 \b {}\b0}\cell 65 | \pard\intbl\qc{\fs20 \b {Xanomeline\line High Dose\line (N=84)}\b0}\cell 66 | \pard\intbl\qc{\fs20 \b {}\b0}\cell 67 | \pard\intbl\qc{\fs20 \b {Fisher's Exact\line p-values}\b0}\cell 68 | \pard\intbl\qc{\fs20 \b {}\b0}\cell 69 | \row 70 | } 71 | 72 | { 73 | \trowd 74 | \trqc \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx3888 75 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx5184 76 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx6092 77 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx7388 78 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx8295 79 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx9591 80 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx10498 81 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx11664 82 | \clbrdrt\clbrdrl\clbrdrb\brdrs\brdrw20\clbrdrr\clvertalb\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx12960 \pard\intbl\qc{\fs20 \b {System Organ Class/\line Preferred Term}\b0}\cell 83 | \pard\intbl\qc{\fs20 \b {n(%)}\b0}\cell 84 | \pard\intbl\qc{\fs20 \b {[AEs]}\b0}\cell 85 | \pard\intbl\qc{\fs20 \b {n(%)}\b0}\cell 86 | \pard\intbl\qc{\fs20 \b {[AEs]}\b0}\cell 87 | \pard\intbl\qc{\fs20 \b {n(%)}\b0}\cell 88 | \pard\intbl\qc{\fs20 \b {[AEs]}\b0}\cell 89 | \pard\intbl\qc{\fs20 \b {Placebo\line vs.\line Low Dose}\b0}\cell 90 | \pard\intbl\qc{\fs20 \b {Placebo\line vs.\line High Dose}\b0}\cell 91 | \row 92 | } 93 | 94 | } 95 | {\footer 96 | \ql 97 | {\f1\fs20\i Note: Treatment emergent events are defined as events which start on or after the start of treatment.}{\f1\fs20\i } 98 | \par\ql 99 | {\f1\fs20\i Note: Adverse events are coded using MedDRA.}{\f1\fs20\i } 100 | \par\ql 101 | {\f1\fs20\i Note: Percentages are based on the number of subjects in the safety population within each treatment group.}{\f1\fs20\i } 102 | \par\ql 103 | {\f1\fs20\i Note: P-values are based on Fisher's Exact test for the comparison of placebo versus each active treatment group. An asterisk is appended to p-values that are less than 0.15.}{\f1\fs20\i } 104 | \par\ql 105 | {\f1\fs20\i Note: The column [AE] represents the total number of times an event was recorded.}{\f1\fs20\i } 106 | \par\ql\tx7245\tqr\tx12960 107 | {\f1\fs20\i Source: programs/t-14-5-02.R}\pmartabqr 108 | {\f1\fs20\i 19:30 Tuesday, June 16, 2020}\par 109 | } 110 | { 111 | \trowd 112 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx3888 113 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx5184 114 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx6092 115 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx7388 116 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx8295 117 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx9591 118 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx10498 119 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx11664 120 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx12960 \pard\intbl\ql{ANY BODY SYSTEM}\cell 121 | \pard\intbl\ql{ 0 }\cell 122 | \pard\intbl\ql{}\cell 123 | \pard\intbl\ql{ 1 ( 1.2%)}\cell 124 | \pard\intbl\ql{[1]}\cell 125 | \pard\intbl\ql{ 2 ( 2.4%)}\cell 126 | \pard\intbl\ql{[2]}\cell 127 | \pard\intbl\ql{0.494 }\cell 128 | \pard\intbl\ql{0.243 }\cell 129 | \row 130 | } 131 | 132 | { 133 | \trowd 134 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx3888 135 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx5184 136 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx6092 137 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx7388 138 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx8295 139 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx9591 140 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx10498 141 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx11664 142 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx12960 \pard\intbl\ql{}\cell 143 | \pard\intbl\ql{}\cell 144 | \pard\intbl\ql{}\cell 145 | \pard\intbl\ql{}\cell 146 | \pard\intbl\ql{}\cell 147 | \pard\intbl\ql{}\cell 148 | \pard\intbl\ql{}\cell 149 | \pard\intbl\ql{}\cell 150 | \pard\intbl\ql{}\cell 151 | \row 152 | } 153 | 154 | { 155 | \trowd 156 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx3888 157 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx5184 158 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx6092 159 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx7388 160 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx8295 161 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx9591 162 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx10498 163 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx11664 164 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx12960 \pard\intbl\ql{NERVOUS SYSTEM DISORDERS}\cell 165 | \pard\intbl\ql{ 0 }\cell 166 | \pard\intbl\ql{}\cell 167 | \pard\intbl\ql{ 1 ( 1.2%)}\cell 168 | \pard\intbl\ql{[1]}\cell 169 | \pard\intbl\ql{ 2 ( 2.4%)}\cell 170 | \pard\intbl\ql{[2]}\cell 171 | \pard\intbl\ql{0.494 }\cell 172 | \pard\intbl\ql{0.243 }\cell 173 | \row 174 | } 175 | 176 | { 177 | \trowd 178 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx3888 179 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx5184 180 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx6092 181 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx7388 182 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx8295 183 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx9591 184 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx10498 185 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx11664 186 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx12960 \pard\intbl\ql{ PARTIAL SEIZURES WITH SECONDARY GENERALISATION}\cell 187 | \pard\intbl\ql{ 0 }\cell 188 | \pard\intbl\ql{}\cell 189 | \pard\intbl\ql{ 0 }\cell 190 | \pard\intbl\ql{}\cell 191 | \pard\intbl\ql{ 1 ( 1.2%)}\cell 192 | \pard\intbl\ql{[1]}\cell 193 | \pard\intbl\ql{}\cell 194 | \pard\intbl\ql{0.494 }\cell 195 | \row 196 | } 197 | 198 | { 199 | \trowd 200 | \trqc \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx3888 201 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx5184 202 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx6092 203 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx7388 204 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx8295 205 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx9591 206 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx10498 207 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx11664 208 | \clbrdrt\clbrdrl\clbrdrb\clbrdrr\clvertalt\clNoWrap\clpadfl0\clpadl80 \clpadft0\clpadt0 \clpadfb0\clpadb0 \clpadfr0\clpadr80 \cellx12960 \pard\intbl\ql{ SYNCOPE}\cell 209 | \pard\intbl\ql{ 0 }\cell 210 | \pard\intbl\ql{}\cell 211 | \pard\intbl\ql{ 1 ( 1.2%)}\cell 212 | \pard\intbl\ql{[1]}\cell 213 | \pard\intbl\ql{ 1 ( 1.2%)}\cell 214 | \pard\intbl\ql{[1]}\cell 215 | \pard\intbl\ql{0.494 }\cell 216 | \pard\intbl\ql{0.494 }\cell 217 | \row 218 | } 219 | 220 | } -------------------------------------------------------------------------------- /programs/config.R: -------------------------------------------------------------------------------- 1 | # config.R 2 | # Same idea as an autoexec script. Sets paths to data libraries and makes 3 | # general settings necessary throughout code 4 | 5 | # Set data library paths ---- 6 | sdtm_lib <- "data/sdtm" 7 | adam_lib <- "data/adam" 8 | 9 | # Reset the col_name behavior to pre huxtable v5 behavior 10 | options(huxtable.add_colnames = FALSE) -------------------------------------------------------------------------------- /programs/t-14-1-01.R: -------------------------------------------------------------------------------- 1 | # t-14-1-01.R 2 | # CDISC Pilot Table 14-1.01 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets 15 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 16 | 17 | # Create the total values upfront for quicker summary ---- 18 | adsl_ <- adsl %>% 19 | union(adsl %>% 20 | mutate(TRT01P = 'Total', 21 | TRT01PN = 99)) %>% 22 | mutate( 23 | COMPL = ifelse(DCDECOD == "COMPLETED", "Y", "N") 24 | ) 25 | 26 | # Calculate the header Ns 27 | header_n <- get_header_n(adsl_) 28 | 29 | # Column headers 30 | column_headers <- header_n %>% select(TRT01PN, labels) %>% 31 | pivot_wider(names_from = TRT01PN, values_from = labels) 32 | 33 | # Intent to treat 34 | itt <- sum_subgrp(adsl_, ITTFL, order_var=STUDYID, include.n=FALSE, header_n = header_n) %>% 35 | mutate(rowlbl1 = "Intent-To-Treat (ITT)") 36 | 37 | # Safety 38 | safety <- sum_subgrp(adsl_, SAFFL, order_var=STUDYID, include.n=FALSE, header_n = header_n) %>% 39 | mutate(rowlbl1 = "Safety") 40 | 41 | # Efficacy 42 | efficacy <- sum_subgrp(adsl_, EFFFL, order_var=STUDYID, include.n=FALSE, header_n = header_n) %>% 43 | mutate(rowlbl1 = "Efficacy") 44 | 45 | # Commpleters Week 24 46 | compl_24 <- sum_subgrp(adsl_, COMP24FL, order_var=STUDYID, include.n=FALSE, header_n = header_n) %>% 47 | mutate(rowlbl1 = "Complete Week 24") 48 | 49 | # Study completers 50 | compl <- sum_subgrp(adsl_, COMPL, order_var=STUDYID, include.n=FALSE, header_n = header_n) %>% 51 | mutate(rowlbl1 = "Complete Study") 52 | 53 | # Pull the body together 54 | body <- rbind(itt, safety, efficacy, compl_24, compl) %>% 55 | filter(rowlbl2 == "Y") %>% 56 | select(-rowlbl2) 57 | 58 | # Cleanup 59 | rm(itt, safety, efficacy, compl_24, compl) 60 | 61 | # Attach the header 62 | final <- bind_rows(column_headers, body) %>% 63 | select(rowlbl1, `0`, `54`, `81`, `99`) 64 | 65 | # Make the table 66 | ht <- as_hux(final, add_colnames = FALSE) %>% 67 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 68 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 69 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 70 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 71 | huxtable::set_width(1.1) %>% 72 | huxtable::set_escape_contents(FALSE) %>% 73 | huxtable::set_col_width(c(.4, .15, .15, .15, .15)) %>% 74 | huxtable::set_wrap(TRUE) 75 | 76 | # Write into doc object and pull titles/footnotes from excel file 77 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 78 | from.file='./data/titles.xlsx', 79 | reader=example_custom_reader, 80 | table_number='14-1.01') %>% 81 | set_font_size(10) %>% 82 | set_ignore_cell_padding(TRUE) %>% 83 | set_column_header_buffer(top=1) 84 | 85 | # Write out the RTF 86 | write_rtf(doc, file='./outputs/14-1.01.rtf') -------------------------------------------------------------------------------- /programs/t-14-1-02.R: -------------------------------------------------------------------------------- 1 | ### Table 14-1.02 Summary of End of Study Data 2 | 3 | library(dplyr) 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(pharmaRTF) 9 | 10 | source('./programs/config.R') 11 | source('./programs/funcs.R') 12 | 13 | #Read in Source and order factors 14 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 15 | adsl$COMP24FL <- ordered(adsl$COMP24FL, c("Y", "N", NA)) 16 | adsl$ARM <- ordered(adsl$ARM, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 17 | adsl$DCREASCD <- ordered(adsl$DCSREAS, c("Adverse Event", 18 | "Death", 19 | "Lack of Efficacy", 20 | "Lost to Follow-up", 21 | "Withdrew Consent", 22 | "Physician Decision", 23 | "I/E Not Met", 24 | "Protocol Violation", 25 | "Sponsor Decision")) 26 | 27 | #### Completion Status Table 28 | comp_stat <- adsl %>% 29 | group_by(COMP24FL, ARM) %>% 30 | summarise(n = n()) 31 | 32 | #Make data.frame for table, unnamed so the cols are named correctly 33 | comp_df <- data.frame( 34 | "Placebo" = n_pct(unlist(comp_stat[c(1,4), "n"]), sum(unlist(comp_stat[c(1,4), "n"])), mark_lt=FALSE), 35 | "Xanomeline Low Dose" = n_pct(unlist(comp_stat[c(2,5), "n"]), sum(unlist(comp_stat[c(2,5), "n"])), mark_lt=FALSE), 36 | "Xanomeline High Dose" = n_pct(unlist(comp_stat[c(3,6), "n"]), sum(unlist(comp_stat[c(3,6), "n"])), mark_lt=FALSE), 37 | "Total" = c(n_pct(sum(comp_stat[1:3, "n"]), sum(comp_stat[,"n"]), mark_lt=FALSE), 38 | n_pct(sum(comp_stat[4:6, "n"]), sum(comp_stat[,"n"]), mark_lt=FALSE)), 39 | row.names = c("\tCompleted Week 24", "\tEarly Termination (prior to Week 24)"), 40 | #Stop data.frame from adding periods 41 | check.names = FALSE, stringsAsFactors = FALSE 42 | ) 43 | # Add tabs to row.names 44 | 45 | # Add missing row. 46 | comp_df["\tMissing", ] <- " 0 ( 0%)" 47 | 48 | # p-value 49 | comp_p <- fish_p(adsl, adsl$COMP24FL, adsl$ARM) 50 | comp_df <- attach_p(comp_df, comp_p) 51 | 52 | #### Reason for Early Termination Table 53 | ## By ARM 54 | term_reas <- adsl %>% 55 | filter(COMP24FL == "N") %>% 56 | group_by(DCREASCD, ARM) %>% 57 | complete(nesting(DCREASCD, ARM)) %>% 58 | summarise(n = n()) 59 | 60 | ## Total 61 | term_reas_tot <- adsl %>% 62 | filter(COMP24FL == "N", !is.na(DCDECOD)) %>% 63 | group_by(DCREASCD) %>% 64 | complete(nesting(DCREASCD, ARM)) %>% 65 | summarise(n = n()) 66 | 67 | 68 | term_df <- data.frame( 69 | "Placebo" = n_pct(unlist(term_reas[seq(1, 27, 3), "n"]), sum(adsl %>% filter(ARM == "Placebo") %>% summarise(n = n())), mark_lt=FALSE), 70 | "Xanomeline Low Dose" = n_pct(unlist(term_reas[seq(2, 27, 3), "n"]), sum(adsl %>% filter(ARM == "Xanomeline Low Dose") %>% summarise(n = n())), mark_lt=FALSE), 71 | "Xanomeline High Dose" = n_pct(unlist(term_reas[seq(3, 27, 3), "n"]), sum(adsl %>% filter(ARM == "Xanomeline High Dose") %>% summarise(n = n())), mark_lt=FALSE), 72 | "Total" = n_pct(unlist(term_reas_tot[, "n"]), sum(adsl %>% summarise(n = n())), mark_lt=FALSE), 73 | row.names = c( 74 | "\tAdverse Event", 75 | "\tDeath", 76 | "\tLack of Efficacy[2]", 77 | "\tLost to Follow-up", 78 | "\tSubject decided to withdraw", 79 | "\tPhysician decided to withdraw subject", 80 | "\tProtocol criteria not met", 81 | "\tProtocol violation", 82 | "\tSponsor decision" 83 | ), 84 | #Stop data.frame from adding periods 85 | check.names = FALSE, stringsAsFactors = FALSE 86 | ) 87 | term_df["\tMissing", ] <- " 0 ( 0%)" 88 | 89 | # p-value 90 | term_p_1 <- adsl %>% 91 | select(ARM, DCREASCD) %>% 92 | mutate(loefl = ifelse(DCREASCD %in% "Adverse Event", 1, 0)) %>% 93 | fish_p(loefl, ARM, width = 6) 94 | term_df <- attach_p(term_df, term_p_1) 95 | 96 | term_p_2 <- adsl %>% 97 | select(ARM, DCREASCD) %>% 98 | mutate(loefl = ifelse(DCREASCD %in% "Lack of Efficacy", 1, 0)) %>% 99 | fish_p(ARM ,loefl, width = 6) 100 | term_df["\tLack of Efficacy[2]",] <- attach_p(term_df[3,], term_p_2) 101 | 102 | 103 | ## Add Table lables 104 | comp_df <- add_column(comp_df, " " = row.names(comp_df), .before = 1) 105 | comp_df <- add_row(comp_df, " " = "Completion Status:", .before = 1) 106 | comp_df <- add_row(comp_df, " " = "", .before = 1) 107 | 108 | term_df <- add_column(term_df, " " = row.names(term_df), .before = 1) 109 | term_df <- add_row(term_df, " " = "Reason for Early Termination (prior to Week 24):", .before = 1) 110 | term_df <- add_row(term_df, " " = "", .before = 1) 111 | 112 | combinedTable <- rbind(comp_df, term_df) 113 | # Rename to get rid of period seperation 114 | names(combinedTable) 115 | 116 | headers <- adsl %>% 117 | group_by(ARM) %>% 118 | summarise(N = n()) 119 | headers_2 <- adsl %>% 120 | summarise(N = n()) %>% 121 | mutate(ARM = "Total") 122 | headers_3 <- rbind(headers, headers_2) %>% 123 | mutate(labels = str_replace_all(str_wrap(glue('{ARM} (N={N})'), width=10), "\n", function(x) "\\line ")) 124 | headers_4 <- c(" ", headers_3$labels, "p-value [1]") 125 | names(combinedTable) <- headers_4 126 | 127 | ht <- combinedTable %>% 128 | huxtable::as_hux(add_colnames=TRUE) %>% 129 | huxtable::set_wrap(FALSE) 130 | 131 | huxtable::bottom_border(ht)[1, ] <- 1 132 | huxtable::bold(ht)[1, ] <- TRUE 133 | huxtable::align(ht)[1, ] <- 'center' 134 | huxtable::align(ht)[, 6] <- "center" 135 | huxtable::width(ht) <- 1.5 136 | huxtable::escape_contents(ht) <- FALSE 137 | huxtable::col_width(ht) <- c(.4, .12, .12, .12, .12, .12) 138 | huxtable::bottom_padding(ht) <- 0 139 | huxtable::top_padding(ht) <- 0 140 | huxtable::valign(ht)[1,] <- "bottom" 141 | ht[8,2] <- "" 142 | ht <- huxtable::merge_cells(ht, 8, 1:2) 143 | 144 | 145 | # Write into doc object and pull titles/footnotes from excel file 146 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 147 | from.file='./data/titles.xlsx', 148 | reader=example_custom_reader, 149 | table_number='14-1.02') %>% 150 | set_font_size(10) %>% 151 | set_ignore_cell_padding(TRUE) %>% 152 | set_column_header_buffer(top = 1) 153 | 154 | # Write out the RTF 155 | write_rtf(doc, file='./outputs/14-1.02.rtf') 156 | 157 | -------------------------------------------------------------------------------- /programs/t-14-1-03.R: -------------------------------------------------------------------------------- 1 | # t-14-1-03.R 2 | # CDISC Pilot Table 14-1.03 3 | 4 | library(dplyr) 5 | library(glue) 6 | library(tidyverse) 7 | library(haven) 8 | library(assertthat) 9 | library(huxtable) 10 | library(pharmaRTF) 11 | 12 | source('./programs/config.R') 13 | source('./programs/funcs.R') 14 | 15 | # Read in the datasets 16 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) %>% 17 | filter(ITTFL == "Y") 18 | 19 | adsl$SITEGR1 <- ordered(adsl$SITEGR1, c( 20 | "Pooled\\line Id", 21 | "701", 22 | "703", 23 | "704", 24 | "705", 25 | "708", 26 | "709", 27 | "710", 28 | "713", 29 | "716", 30 | "718", 31 | "900", 32 | "TOTAL" 33 | )) 34 | adsl$SITEID <- ordered(adsl$SITEID, c( 35 | "Site\\line Id", 36 | "701", 37 | "703", 38 | "704", 39 | "705", 40 | "708", 41 | "709", 42 | "710", 43 | "713", 44 | "716", 45 | "718", 46 | "702", 47 | "706", 48 | "707", 49 | "711", 50 | "714", 51 | "715", 52 | "717", 53 | "" 54 | )) 55 | adsl$ITTFL <- ordered(adsl$ITTFL, c("Y", "N")) 56 | adsl$EFFFL <- ordered(adsl$EFFFL, c("Y", "N")) 57 | adsl$COMP24FL <- ordered(adsl$COMP24FL, c("Y", "N")) 58 | 59 | 60 | 61 | adsl_grp1 <- adsl %>% 62 | select(SITEGR1, SITEID, TRT01P, ITTFL) %>% 63 | group_by(SITEGR1, SITEID, TRT01P, ITTFL) %>% 64 | filter(ITTFL == "Y") %>% 65 | summarise(n = n()) 66 | adsl_grp1[,4] <- "ITTFL" 67 | names(adsl_grp1)[4] <- "FLFL" 68 | adsl_grp2 <- adsl %>% 69 | select(SITEGR1, SITEID, TRT01P, EFFFL) %>% 70 | group_by(SITEGR1, SITEID, TRT01P, EFFFL) %>% 71 | filter(EFFFL == "Y") %>% 72 | summarise(n = n()) 73 | adsl_grp2[,4] <- "EFFFL" 74 | names(adsl_grp2)[4] <- "FLFL" 75 | adsl_grp3 <- adsl %>% 76 | select(SITEGR1, SITEID, TRT01P, COMP24FL) %>% 77 | group_by(SITEGR1, SITEID, TRT01P, COMP24FL) %>% 78 | filter(COMP24FL == "Y") %>% 79 | summarise(n = n()) 80 | adsl_grp3[,4] <- "COMP24FL" 81 | names(adsl_grp3)[4] <- "FLFL" 82 | adsl_grp4 <- adsl %>% 83 | select(SITEGR1, SITEID, ITTFL) %>% 84 | group_by(SITEGR1, SITEID, ITTFL) %>% 85 | filter(ITTFL == "Y") %>% 86 | summarise(n = n()) 87 | adsl_grp4[,3] <- "ITTFL" 88 | names(adsl_grp4)[3] <- "FLFL" 89 | adsl_grp4$TRT01P <- "Total" 90 | adsl_grp5 <- adsl %>% 91 | select(SITEGR1, SITEID, EFFFL) %>% 92 | group_by(SITEGR1, SITEID, EFFFL) %>% 93 | filter(EFFFL == "Y") %>% 94 | summarise(n = n()) 95 | adsl_grp5[,3] <- "EFFFL" 96 | names(adsl_grp5)[3] <- "FLFL" 97 | adsl_grp5$TRT01P <- "Total" 98 | adsl_grp6 <- adsl %>% 99 | select(SITEGR1, SITEID, COMP24FL) %>% 100 | group_by(SITEGR1, SITEID, COMP24FL) %>% 101 | filter(COMP24FL == "Y") %>% 102 | summarise(n = n()) 103 | adsl_grp6[,3] <- "COMP24FL" 104 | names(adsl_grp6)[3] <- "FLFL" 105 | adsl_grp6$TRT01P <- "Total" 106 | 107 | all <- rbind(adsl_grp1, adsl_grp2, adsl_grp3, adsl_grp4, adsl_grp5, adsl_grp6) 108 | all$FLFL <- ordered(all$FLFL, c("ITTFL", "EFFFL", "COMP24FL")) 109 | all$TRT01P <- ordered(all$TRT01P, c( 110 | "Placebo", 111 | "Xanomeline Low Dose", 112 | "Xanomeline High Dose", 113 | "Total" 114 | )) 115 | df <- all %>% 116 | arrange(SITEGR1, SITEID, TRT01P, FLFL) %>% 117 | pivot_wider(id_cols = c(SITEGR1, SITEID), names_from = c(TRT01P, FLFL), values_from = c(n), values_fill = list(n = 0)) %>% 118 | ungroup() %>% 119 | as.data.frame() 120 | 121 | # Stack the total row to the bottom of the data frame 122 | df <-rbind(df, 123 | data.frame( 124 | SITEGR1 = "TOTAL", 125 | SITEID = "", 126 | t(apply(df[,3:ncol(df)], 2, sum)), check.names = FALSE 127 | ) 128 | ) 129 | 130 | names(df) <- c( 131 | "Pooled\\line Id", 132 | "Site\\line Id", 133 | rep(c("ITT", "Eff", "Com"), 4) 134 | ) 135 | 136 | df[2:(nrow(df) + 1),] <- df[1:nrow(df),] 137 | df[1,] <- as.list(names(df)) 138 | df <- df %>% 139 | add_row("Pooled\\line Id" = "", .before = 1) %>% 140 | add_row("Pooled\\line Id" = "", .before = 1) 141 | 142 | 143 | ### Add Headers 144 | headers <- adsl %>% 145 | group_by(ARM) %>% 146 | summarise(N = n()) %>% 147 | mutate(labels = str_replace_all(str_wrap(glue('{ARM} (N={N})'), width=10), "\n", function(x) "\\line ")) 148 | headers[4,] <- list( 149 | ARM = "Total", 150 | N = nrow(adsl), 151 | labels = paste0("Total\\line(N=", nrow(adsl), ")") 152 | ) 153 | 154 | df[1, 3] <- headers[1, "labels"] 155 | df[1, 6] <- headers[3, "labels"] 156 | df[1, 9] <- headers[2, "labels"] 157 | df[1, 12] <- headers[4, "labels"] 158 | 159 | ht <- df %>% 160 | huxtable::as_hux(add_colnames=FALSE) %>% 161 | merge_cells(1, 3:5) %>% 162 | set_bottom_border(2, 3:5, 1) %>% 163 | merge_cells(1, 6:8) %>% 164 | set_bottom_border(2, 6:8, 1) %>% 165 | merge_cells(1, 9:11) %>% 166 | set_bottom_border(2, 9:11, 1) %>% 167 | merge_cells(1, 12:14) %>% 168 | set_bottom_border(2, 12:14, 1) %>% 169 | set_escape_contents(FALSE) %>% 170 | set_width(1.1) %>% 171 | set_bottom_border(3, 1:14, 1) %>% 172 | huxtable::set_align(3, 1:14, "center") %>% 173 | huxtable::set_valign(3, 1:14, "bottom") %>% 174 | huxtable::set_align(4:nrow(df), 3:ncol(df), "right") %>% 175 | huxtable::set_align(1:nrow(df), 1:2, "center") %>% 176 | huxtable::set_align(1, 1:14, "center") %>% 177 | huxtable::set_valign(1, 1:14, "bottom") %>% 178 | huxtable::set_col_width(1:ncol(df), value = c(0.1, 0.1, rep(0.07, 12))) %>% 179 | huxtable::set_wrap(FALSE) 180 | 181 | doc <- rtf_doc(ht, header_rows = 2) %>% titles_and_footnotes_from_df( 182 | from.file='./data/titles.xlsx', 183 | reader=example_custom_reader, 184 | table_number='14-1.03') %>% 185 | set_font_size(10) %>% 186 | set_ignore_cell_padding(TRUE) %>% 187 | set_column_header_buffer(top = 1) 188 | 189 | write_rtf(doc, file='./outputs/14-1.03.rtf') 190 | 191 | -------------------------------------------------------------------------------- /programs/t-14-2-01.R: -------------------------------------------------------------------------------- 1 | # t-14-2-01.R 2 | # CDISC Pilot Table 14-2.01 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(pharmaRTF) 9 | 10 | source('./programs/config.R') 11 | source('./programs/funcs.R') 12 | 13 | # Import and explore the data frame ---- 14 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) %>% 15 | filter(ITTFL == "Y") %>% 16 | mutate( 17 | RACE_DISPLAY = case_when( 18 | ETHNIC == 'HISPANIC OR LATINO' ~ 'Hispanic', 19 | RACE == 'WHITE' ~ 'Caucasian', 20 | RACE == 'BLACK OR AFRICAN AMERICAN' ~ 'African Descent', 21 | RACE == 'AMERICAN INDIAN OR ALASKA NATIVE' ~ 'Other', 22 | ), 23 | RACEN_DISPLAY = case_when( 24 | ETHNIC == 'HISPANIC OR LATINO' ~ 3, 25 | RACE == 'WHITE' ~ 1, 26 | RACE == 'BLACK OR AFRICAN AMERICAN' ~ 2, 27 | RACE == 'AMERICAN INDIAN OR ALASKA NATIVE' ~ 4, 28 | ), 29 | SEX = 30 | case_when( 31 | SEX == 'M' ~ 'Male', 32 | SEX == 'F' ~ 'Female' 33 | ), 34 | SEXN = 35 | case_when( 36 | SEX == 'Male' ~ 1, 37 | SEX == 'Female' ~ 2 38 | ), 39 | DURDSGR1N = 40 | case_when( 41 | DURDSGR1 == '<12' ~ 1, 42 | DURDSGR1 == '>=12' ~ 2 43 | ), 44 | DURDSGR1 = paste(DURDSGR1, 'months'), 45 | BMIBLGR1N = 46 | case_when( 47 | BMIBLGR1 == '<25' ~ 1, 48 | BMIBLGR1 == '25-<30' ~ 2, 49 | BMIBLGR1 == '>=30' ~ 3 50 | ), 51 | AGEGR1 = paste(AGEGR1, 'yrs') 52 | ) 53 | 54 | get_meta(adsl) 55 | 56 | # Create the total values upfront for quicker summary ---- 57 | adsl_ <- adsl %>% 58 | bind_rows(adsl %>% 59 | mutate(TRT01P = 'Total', 60 | TRT01PN = 99)) 61 | 62 | 63 | # Get the header N's ---- 64 | header_n <- get_header_n(adsl_) 65 | 66 | ## Exploring Age ---- 67 | 68 | # Descriptive stats 69 | age_1 <- adsl_ %>% desc_stats(AGE) 70 | age_p <- adsl %>% aov_p(AGE ~ TRT01P) # anova 71 | 72 | age_1 <- attach_p(age_1, age_p) 73 | 74 | # Categorical n counts 75 | age_2 <- adsl_ %>% sum_subgrp(AGEGR1, AGEGR1N, include.n=FALSE, header_n=header_n) 76 | 77 | agegrp_p <- adsl %>% chi_p(AGEGR1, TRT01P) 78 | age_2 <- attach_p(age_2, agegrp_p) 79 | 80 | age <- rbind(age_1, age_2) %>% 81 | mutate(rowlbl1 = "Age (y)") 82 | 83 | rm(age_1, age_2, age_p, agegrp_p) 84 | 85 | ## Exploring sex ---- 86 | sex = adsl_ %>% 87 | sum_subgrp(SEX, SEXN, header_n=header_n) 88 | 89 | sex_p <- adsl %>% chi_p(SEX, TRT01P) 90 | 91 | sex <- attach_p(sex, sex_p) %>% 92 | mutate(rowlbl1 = 'Sex') 93 | 94 | rm(sex_p) 95 | 96 | ## Exploring race ---- 97 | race = adsl_ %>% 98 | sum_subgrp(RACE_DISPLAY, RACEN_DISPLAY, header_n=header_n) %>% 99 | rowwise() %>% 100 | mutate( 101 | rowlbl1 = "Race (Origin)", 102 | ) 103 | 104 | race_p <- adsl %>% chi_p(RACE_DISPLAY, TRT01P) 105 | 106 | race <- attach_p(race, race_p) 107 | 108 | rm(race_p) 109 | 110 | ## Exploring MMSE --- 111 | mmse <- adsl_ %>% desc_stats(MMSETOT) %>% 112 | mutate( 113 | rowlbl1 = 'MMSE' 114 | ) 115 | 116 | mmse_p <- adsl %>% aov_p(MMSETOT ~ TRT01P) 117 | 118 | mmse <- attach_p(mmse, mmse_p) 119 | 120 | rm(mmse_p) 121 | 122 | ## Exploring disease duration ---- 123 | 124 | # Descriptive 125 | durdis_1 <- adsl_ %>% desc_stats(DURDIS) 126 | durdis_1p <- adsl %>% aov_p(DURDIS ~ TRT01P) 127 | durdis_1 <- attach_p(durdis_1, durdis_1p) 128 | 129 | # Categorical 130 | durdis_2 <- adsl_ %>% sum_subgrp(DURDSGR1, DURDSGR1N, include.n=FALSE, header_n=header_n) 131 | durdis_2p <- adsl %>% chi_p(DURDSGR1, TRT01P) 132 | durdis_2 <- attach_p(durdis_2, durdis_2p) 133 | 134 | durdis <- durdis_1 %>% 135 | union(durdis_2) %>% 136 | mutate( 137 | rowlbl1 = 'Duration of disease ' 138 | ) %>% 139 | pad_row() 140 | 141 | rm(durdis_1, durdis_2, durdis_1p, durdis_2p) 142 | 143 | ## Years of education ---- 144 | educlvl <- adsl_ %>% desc_stats(EDUCLVL) %>% 145 | mutate( 146 | rowlbl1 = 'Years of education' 147 | ) 148 | educlvl_p <- adsl %>% aov_p(EDUCLVL ~ TRT01P) 149 | educlvl <- attach_p(educlvl, educlvl_p) 150 | 151 | rm(educlvl_p) 152 | 153 | ## Baseline weight ---- 154 | weightbl <- adsl_ %>% desc_stats(WEIGHTBL) %>% 155 | mutate( 156 | rowlbl1 = 'Baseline weight(kg)' 157 | ) 158 | weightbl_p <- adsl %>% aov_p(WEIGHTBL ~ TRT01P) 159 | weightbl <- attach_p(weightbl, weightbl_p) 160 | 161 | rm(weightbl_p) 162 | 163 | ## Baseline height ---- 164 | heightbl <- adsl_ %>% desc_stats(HEIGHTBL) %>% 165 | mutate( 166 | rowlbl1 = 'Baseline height(cm)' 167 | ) 168 | heightbl_p <- adsl %>% aov_p(HEIGHTBL ~ TRT01P) 169 | heightbl <- attach_p(heightbl, heightbl_p) 170 | 171 | rm(heightbl_p) 172 | 173 | ## Baseline BMI ---- 174 | 175 | # Descriptive 176 | bmi_1 <- adsl_ %>% desc_stats(BMIBL) 177 | bmi_1p <- adsl %>% aov_p(BMIBL ~ TRT01P) 178 | bmi_1 <- attach_p(bmi_1, bmi_1p) 179 | 180 | # Categorical 181 | bmi_2 <- adsl_ %>% sum_subgrp(BMIBLGR1, BMIBLGR1N, include.n=FALSE, header_n=header_n) 182 | bmi_2p <- adsl %>% chi_p(BMIBLGR1, TRT01P) 183 | bmi_2 <- attach_p(bmi_2, bmi_2p) 184 | 185 | bmi <- rbind(bmi_1, bmi_2) %>% 186 | mutate( 187 | rowlbl1 = 'Baseline BMI' 188 | ) 189 | 190 | rm(bmi_1, bmi_2, bmi_1p, bmi_2p) 191 | 192 | ## Stack together final tables --- 193 | final <- rbind(age, sex, race, mmse, durdis, educlvl, weightbl, heightbl, bmi) %>% 194 | group_by(rowlbl1) %>% 195 | mutate(ord1 = row_number()) %>% 196 | ungroup() %>% 197 | mutate(rowlbl1 = ifelse(ord1 == 1, rowlbl1, "")) 198 | 199 | rm(age, sex, race, mmse, durdis, educlvl, weightbl, heightbl, bmi) 200 | 201 | # Make and attach column headers 202 | header_n_v <- header_n %>% select(TRT01PN, labels) %>% 203 | pivot_wider(names_from = TRT01PN, values_from = labels) %>% 204 | mutate( 205 | rowlbl1 = '', 206 | rowlbl2 = '', 207 | p = 'p-value\\line [1]' 208 | ) 209 | 210 | final <- bind_rows(header_n_v, final) %>% 211 | select(rowlbl1, rowlbl2, `0`, `54`, `81`, `99`, p) 212 | 213 | ## Table build and RTF Output 214 | ht <- huxtable::as_hux(final, add_colnames = FALSE) 215 | 216 | # ht <- as_hux(mtcars, add_colnames = TRUE) 217 | huxtable::bottom_border(ht)[1, ] <- 1 218 | huxtable::valign(ht)[1, ] <- 'bottom' 219 | huxtable::bold(ht)[1, ] <- TRUE 220 | huxtable::align(ht)[1, ] <- 'center' 221 | huxtable::width(ht) <- 1.5 222 | huxtable::escape_contents(ht) <- FALSE 223 | huxtable::col_width(ht) <- c(.2, .2, .12, .12, .12, .12, .12) 224 | huxtable::bottom_padding(ht) <- 0 225 | huxtable::top_padding(ht) <- 0 226 | 227 | # Write into doc object and pull titles/footnotes from excel file 228 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 229 | from.file='./data/titles.xlsx', 230 | reader=example_custom_reader, 231 | table_number='14-2.01') %>% 232 | set_font_size(10) %>% 233 | set_ignore_cell_padding(TRUE) %>% 234 | set_column_header_buffer(top=1) 235 | 236 | # Write out the RTF 237 | write_rtf(doc, file='./outputs/14-2.01.rtf') 238 | -------------------------------------------------------------------------------- /programs/t-14-3-01.R: -------------------------------------------------------------------------------- 1 | # t-14-3-01.R 2 | # CDISC Pilot Table 14-3.01 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | adas <- read_xpt(glue("{adam_lib}/adadas.xpt")) %>% 16 | filter(EFFFL == "Y" & ITTFL=='Y' & PARAMCD == 'ACTOT' & ANL01FL == 'Y') 17 | 18 | # Calculate the header Ns ---- 19 | header_n <- adas %>% 20 | distinct(USUBJID, TRTP, TRTPN) %>% 21 | get_header_n(TRTP, TRTPN) 22 | 23 | column_headers <- header_n %>% 24 | select(-N) %>% 25 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 26 | mutate(rowlbl1 = '') 27 | 28 | # Run each group 29 | summary_portion <- bind_rows(summary_data(adas, AVAL, 0 , 'Baseline'), 30 | summary_data(adas, AVAL, 24, 'Week 24'), 31 | summary_data(adas, CHG, 24, 'Change from Baseline')) %>% 32 | pad_row() 33 | 34 | # Gather the model data 35 | model_portion <- efficacy_models(adas, 'CHG', 24) 36 | 37 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 38 | select(rowlbl1, `0`, `54`, `81`) 39 | 40 | ## Create the table 41 | 42 | # Make the table 43 | ht <- as_hux(final, add_colnames = FALSE) %>% 44 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 45 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 46 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 47 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 48 | huxtable::set_width(1.2) %>% 49 | huxtable::set_escape_contents(FALSE) %>% 50 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 51 | ht 52 | 53 | # Write into doc object and pull titles/footnotes from excel file 54 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 55 | from.file='./data/titles.xlsx', 56 | reader=example_custom_reader, 57 | table_number='14-3.01') %>% 58 | set_font_size(10) %>% 59 | set_ignore_cell_padding(TRUE) %>% 60 | set_column_header_buffer(top=1) 61 | 62 | # Write out the RTF 63 | write_rtf(doc, file='./outputs/14-3.01.rtf') 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /programs/t-14-3-02.R: -------------------------------------------------------------------------------- 1 | # t-14-3-02.R 2 | # CDISC Pilot Table 14-3.02 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | cibc <- read_xpt(glue("{adam_lib}/adcibc.xpt")) %>% 16 | filter(EFFFL == "Y" & ITTFL=='Y' & PARAMCD == 'CIBICVAL' & ANL01FL == 'Y') 17 | 18 | # Calculate the header Ns ---- 19 | header_n <- cibc %>% 20 | distinct(USUBJID, TRTP, TRTPN) %>% 21 | get_header_n(TRTP, TRTPN) 22 | 23 | column_headers <- header_n %>% 24 | select(-N) %>% 25 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 26 | mutate(rowlbl1 = '') 27 | 28 | # Run each group 29 | summary_portion <- summary_data(cibc, AVAL, 24, 'Week 24') %>% 30 | pad_row() 31 | 32 | # Gather the model data 33 | model_portion <- efficacy_models(cibc, 'AVAL', 24) 34 | 35 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 36 | select(rowlbl1, `0`, `54`, `81`) 37 | 38 | ## Create the table 39 | 40 | # Make the table 41 | ht <- as_hux(final, add_colnames = FALSE) %>% 42 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 43 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 44 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 45 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 46 | huxtable::set_width(1.2) %>% 47 | huxtable::set_escape_contents(FALSE) %>% 48 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 49 | ht 50 | 51 | # Write into doc object and pull titles/footnotes from excel file 52 | ## TODO: `titles_and_footnotes_from_df`` should be an exported function so remove internal reference when updated 53 | doc <- rtf_doc(ht) %>% pharmaRTF:::titles_and_footnotes_from_df( 54 | from.file='./data/titles.xlsx', 55 | reader=example_custom_reader, 56 | table_number='14-3.02') %>% 57 | set_font_size(10) %>% 58 | set_ignore_cell_padding(TRUE) %>% 59 | set_column_header_buffer(top=1) 60 | 61 | # Write out the RTF 62 | write_rtf(doc, file='./outputs/14-3.02.rtf') 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /programs/t-14-3-03.R: -------------------------------------------------------------------------------- 1 | # t-14-3-03.R 2 | # CDISC Pilot Table 14-3.03 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | adas <- read_xpt(glue("{adam_lib}/adadas.xpt")) %>% 16 | filter(EFFFL == "Y" & ITTFL=='Y' & PARAMCD == 'ACTOT' & ANL01FL == 'Y') 17 | 18 | # Calculate the header Ns ---- 19 | header_n <- adas %>% 20 | distinct(USUBJID, TRTP, TRTPN) %>% 21 | get_header_n(TRTP, TRTPN) 22 | 23 | column_headers <- header_n %>% 24 | select(-N) %>% 25 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 26 | mutate(rowlbl1 = '') 27 | 28 | # Run each group 29 | summary_portion <- bind_rows(summary_data(adas, AVAL, 0, 'Baseline'), 30 | summary_data(adas, AVAL, 8, 'Week 8'), 31 | summary_data(adas, CHG, 8, 'Change from Baseline')) %>% 32 | pad_row() 33 | 34 | # Gather the model data 35 | model_portion <- efficacy_models(adas, 'CHG', 8) 36 | 37 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 38 | select(rowlbl1, `0`, `54`, `81`) 39 | 40 | # Make the table 41 | ht <- as_hux(final, add_colnames = FALSE) %>% 42 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 43 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 44 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 45 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 46 | huxtable::set_width(1.2) %>% 47 | huxtable::set_escape_contents(FALSE) %>% 48 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 49 | ht 50 | 51 | # Write into doc object and pull titles/footnotes from excel file 52 | doc <- rtf_doc(ht) %>% pharmaRTF:::titles_and_footnotes_from_df( 53 | from.file='./data/titles.xlsx', 54 | reader=example_custom_reader, 55 | table_number='14-3.03') %>% 56 | set_font_size(10) %>% 57 | set_ignore_cell_padding(TRUE) %>% 58 | set_column_header_buffer(top=1) 59 | 60 | # Write out the RTF 61 | write_rtf(doc, file='./outputs/14-3.03.rtf') 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /programs/t-14-3-04.R: -------------------------------------------------------------------------------- 1 | # t-14-3-02.R 2 | # CDISC Pilot Table 14-3.02 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | cibc <- read_xpt(glue("{adam_lib}/adcibc.xpt")) %>% 16 | filter(EFFFL == "Y" & ITTFL=='Y' & PARAMCD == 'CIBICVAL' & ANL01FL == 'Y') 17 | 18 | # Calculate the header Ns ---- 19 | header_n <- cibc %>% 20 | distinct(USUBJID, TRTP, TRTPN) %>% 21 | get_header_n(TRTP, TRTPN) 22 | 23 | column_headers <- header_n %>% 24 | select(-N) %>% 25 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 26 | mutate(rowlbl1 = '') 27 | 28 | # Run each group 29 | summary_portion <- summary_data(cibc, AVAL, 8, 'Week 8') %>% 30 | pad_row() 31 | 32 | # Gather the model data 33 | model_portion <- efficacy_models(cibc, 'AVAL', 8) 34 | 35 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 36 | select(rowlbl1, `0`, `54`, `81`) 37 | 38 | # Make the table 39 | ht <- as_hux(final) %>% 40 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 41 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 42 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 43 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 44 | huxtable::set_width(1.2) %>% 45 | huxtable::set_escape_contents(FALSE) %>% 46 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 47 | ht 48 | 49 | # Write into doc object and pull titles/footnotes from excel file 50 | ## TODO: `titles_and_footnotes_from_df`` should be an exported function so remove internal reference when updated 51 | doc <- rtf_doc(ht) %>% pharmaRTF:::titles_and_footnotes_from_df( 52 | from.file='./data/titles.xlsx', 53 | reader=example_custom_reader, 54 | table_number='14-3.04') %>% 55 | set_font_size(10) %>% 56 | set_ignore_cell_padding(TRUE) %>% 57 | set_column_header_buffer(top=1) 58 | 59 | # Write out the RTF 60 | write_rtf(doc, file='./outputs/14-3.04.rtf') 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /programs/t-14-3-05.R: -------------------------------------------------------------------------------- 1 | # t-14-3-05.R 2 | # CDISC Pilot Table 14-3.05 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | adas <- read_xpt(glue("{adam_lib}/adadas.xpt")) %>% 16 | filter(EFFFL == "Y" & ITTFL=='Y' & PARAMCD == 'ACTOT' & ANL01FL == 'Y') 17 | 18 | # Calculate the header Ns ---- 19 | header_n <- adas %>% 20 | distinct(USUBJID, TRTP, TRTPN) %>% 21 | get_header_n(TRTP, TRTPN) 22 | 23 | column_headers <- header_n %>% 24 | select(-N) %>% 25 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 26 | mutate(rowlbl1 = '') 27 | 28 | # Run each group 29 | summary_portion <- bind_rows(summary_data(adas, AVAL, 0, 'Baseline'), 30 | summary_data(adas, AVAL, 16, 'Week 16'), 31 | summary_data(adas, CHG, 16, 'Change from Baseline')) %>% 32 | pad_row() 33 | 34 | # Gather the model data 35 | model_portion <- efficacy_models(adas, 'CHG', 16) 36 | 37 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 38 | select(rowlbl1, `0`, `54`, `81`) 39 | 40 | # Make the table 41 | ht <- as_hux(final) %>% 42 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 43 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 44 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 45 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 46 | huxtable::set_width(1.2) %>% 47 | huxtable::set_escape_contents(FALSE) %>% 48 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 49 | ht 50 | 51 | # Write into doc object and pull titles/footnotes from excel file 52 | doc <- rtf_doc(ht) %>% pharmaRTF:::titles_and_footnotes_from_df( 53 | from.file='./data/titles.xlsx', 54 | reader=example_custom_reader, 55 | table_number='14-3.05') %>% 56 | set_font_size(10) %>% 57 | set_ignore_cell_padding(TRUE) %>% 58 | set_column_header_buffer(top=1) 59 | 60 | # Write out the RTF 61 | write_rtf(doc, file='./outputs/14-3.05.rtf') 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /programs/t-14-3-06.R: -------------------------------------------------------------------------------- 1 | # t-14-3-06.R 2 | # CDISC Pilot Table 14-3.06 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | cibc <- read_xpt(glue("{adam_lib}/adcibc.xpt")) %>% 16 | filter(EFFFL == "Y" & ITTFL=='Y' & PARAMCD == 'CIBICVAL' & ANL01FL == 'Y') 17 | 18 | # Calculate the header Ns ---- 19 | header_n <- cibc %>% 20 | distinct(USUBJID, TRTP, TRTPN) %>% 21 | get_header_n(TRTP, TRTPN) 22 | 23 | column_headers <- header_n %>% 24 | select(-N) %>% 25 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 26 | mutate(rowlbl1 = '') 27 | 28 | # Run each group 29 | summary_portion <- summary_data(cibc, AVAL, 16, 'Week 16') %>% 30 | pad_row() 31 | 32 | # Gather the model data 33 | model_portion <- efficacy_models(cibc, 'VAL', 16) 34 | 35 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 36 | select(rowlbl1, `0`, `54`, `81`) 37 | 38 | # Make the table 39 | ht <- as_hux(final) %>% 40 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 41 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 42 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 43 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 44 | huxtable::set_width(1.2) %>% 45 | huxtable::set_escape_contents(FALSE) %>% 46 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 47 | ht 48 | 49 | # Write into doc object and pull titles/footnotes from excel file 50 | ## TODO: `titles_and_footnotes_from_df`` should be an exported function so remove internal reference when updated 51 | doc <- rtf_doc(ht) %>% pharmaRTF:::titles_and_footnotes_from_df( 52 | from.file='./data/titles.xlsx', 53 | reader=example_custom_reader, 54 | table_number='14-3.06') %>% 55 | set_font_size(10) %>% 56 | set_ignore_cell_padding(TRUE) %>% 57 | set_column_header_buffer(top=1) 58 | 59 | # Write out the RTF 60 | write_rtf(doc, file='./outputs/14-3.06.rtf') 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /programs/t-14-3-07.R: -------------------------------------------------------------------------------- 1 | # t-14-3-07.R 2 | # CDISC Pilot Table 14-3.07 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | adas <- read_xpt(glue("{adam_lib}/adadas.xpt")) %>% 16 | filter(COMP24FL == "Y" & EFFFL=='Y' & PARAMCD == 'ACTOT' & ANL01FL == 'Y' & DTYPE != 'LOCF') 17 | # NOTE!: Despite following the analysis results metadata in the CDISC Pilot Define.xml, the baseline counts 18 | # on Placebo and Xan Lo are off by 1. We have 60 and 28 respectively. This was confirmed on both this 19 | # cut of data and following the ARM on the original cut of data as well. 20 | 21 | # Calculate the header Ns ---- 22 | header_n <- adas %>% 23 | distinct(USUBJID, TRTP, TRTPN) %>% 24 | get_header_n(TRTP, TRTPN) 25 | 26 | column_headers <- header_n %>% 27 | select(-N) %>% 28 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 29 | mutate(rowlbl1 = '') 30 | 31 | # Run each group 32 | summary_portion <- bind_rows(summary_data(adas, AVAL, 0, 'Baseline'), 33 | summary_data(adas, AVAL, 24, 'Week 24'), 34 | summary_data(adas, CHG, 24, 'Change from Baseline')) %>% 35 | pad_row() 36 | 37 | # Gather the model data 38 | model_portion <- efficacy_models(adas, 'CHG', 24) 39 | 40 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 41 | select(rowlbl1, `0`, `54`, `81`) 42 | 43 | # Make the table 44 | ht <- as_hux(final) %>% 45 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 46 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 47 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 48 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 49 | huxtable::set_width(1.2) %>% 50 | huxtable::set_escape_contents(FALSE) %>% 51 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 52 | ht 53 | 54 | 55 | # Write into doc object and pull titles/footnotes from excel file 56 | ## TODO: `titles_and_footnotes_from_df`` should be an exported function so remove internal reference when updated 57 | doc <- rtf_doc(ht) %>% pharmaRTF:::titles_and_footnotes_from_df( 58 | from.file='./data/titles.xlsx', 59 | reader=example_custom_reader, 60 | table_number='14-3.07') %>% 61 | set_font_size(10) %>% 62 | set_ignore_cell_padding(TRUE) %>% 63 | set_column_header_buffer(top=1) 64 | 65 | # Write out the RTF 66 | write_rtf(doc, file='./outputs/14-3.07.rtf') 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /programs/t-14-3-08.R: -------------------------------------------------------------------------------- 1 | # t-14-3-08.R 2 | # CDISC Pilot Table 14-3.08 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | adas <- read_xpt(glue("{adam_lib}/adadas.xpt")) %>% 16 | filter(EFFFL=='Y' & PARAMCD == 'ACTOT' & ANL01FL == 'Y' & SEX == "M") 17 | 18 | # Calculate the header Ns ---- 19 | header_n <- adas %>% 20 | distinct(USUBJID, TRTP, TRTPN) %>% 21 | get_header_n(TRTP, TRTPN) 22 | 23 | column_headers <- header_n %>% 24 | select(-N) %>% 25 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 26 | mutate(rowlbl1 = '') 27 | 28 | # Run each group 29 | summary_portion <- bind_rows(summary_data(adas, AVAL, 0, 'Baseline'), 30 | summary_data(adas, AVAL, 24, 'Week 24'), 31 | summary_data(adas, CHG, 24, 'Change from Baseline')) %>% 32 | pad_row() 33 | 34 | # Gather the model data 35 | model_portion <- efficacy_models(adas, 'CHG', 24) 36 | 37 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 38 | select(rowlbl1, `0`, `54`, `81`) 39 | 40 | # Make the table 41 | ht <- as_hux(final) %>% 42 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 43 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 44 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 45 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 46 | huxtable::set_width(1.2) %>% 47 | huxtable::set_escape_contents(FALSE) %>% 48 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 49 | ht 50 | 51 | # Write into doc object and pull titles/footnotes from excel file 52 | ## TODO: `titles_and_footnotes_from_df`` should be an exported function so remove internal reference when updated 53 | doc <- rtf_doc(ht) %>% pharmaRTF:::titles_and_footnotes_from_df( 54 | from.file='./data/titles.xlsx', 55 | reader=example_custom_reader, 56 | table_number='14-3.08') %>% 57 | set_font_size(10) %>% 58 | set_ignore_cell_padding(TRUE) %>% 59 | set_column_header_buffer(top=1) 60 | 61 | # Write out the RTF 62 | write_rtf(doc, file='./outputs/14-3.08.rtf') 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /programs/t-14-3-09.R: -------------------------------------------------------------------------------- 1 | # t-14-3-09.R 2 | # CDISC Pilot Table 14-3.09 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | adas <- read_xpt(glue("{adam_lib}/adadas.xpt")) %>% 16 | filter(EFFFL == "Y" & PARAMCD == 'ACTOT' & ANL01FL == 'Y' & SEX == "F") 17 | 18 | # Calculate the header Ns ---- 19 | header_n <- adas %>% 20 | distinct(USUBJID, TRTP, TRTPN) %>% 21 | get_header_n(TRTP, TRTPN) 22 | 23 | column_headers <- header_n %>% 24 | select(-N) %>% 25 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 26 | mutate(rowlbl1 = '') 27 | 28 | # Run each group 29 | summary_portion <- bind_rows(summary_data(adas, AVAL, 0, 'Baseline'), 30 | summary_data(adas, AVAL, 24, 'Week 24'), 31 | summary_data(adas, CHG, 24, 'Change from Baseline')) %>% 32 | pad_row() 33 | 34 | # Gather the model data 35 | model_portion <- efficacy_models(adas, 'CHG', 24) 36 | 37 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 38 | select(rowlbl1, `0`, `54`, `81`) 39 | 40 | # Make the table 41 | ht <- as_hux(final) %>% 42 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 43 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 44 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 45 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 46 | huxtable::set_width(1.2) %>% 47 | huxtable::set_escape_contents(FALSE) %>% 48 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 49 | 50 | # Write into doc object and pull titles/footnotes from excel file 51 | doc <- rtf_doc(ht) %>% pharmaRTF:::titles_and_footnotes_from_df( 52 | from.file='./data/titles.xlsx', 53 | reader=example_custom_reader, 54 | table_number='14-3.09') %>% 55 | set_font_size(10) %>% 56 | set_ignore_cell_padding(TRUE) %>% 57 | set_column_header_buffer(top=1) 58 | 59 | # Write out the RTF 60 | write_rtf(doc, file='./outputs/14-3.09.rtf') 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /programs/t-14-3-10.R: -------------------------------------------------------------------------------- 1 | # t-14-3-09.R 2 | # CDISC Pilot Table 14-3.10 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADAS datasets and filter ---- 15 | adas <- read_xpt(glue("{adam_lib}/adadas.xpt")) %>% 16 | filter(EFFFL == "Y" & PARAMCD == "ACTOT" & ITTFL == "Y" & AVISITN %in% c(0, 8, 16, 24) & ANL01FL=="Y") %>% 17 | mutate(SET = "LOCF") %>% 18 | select(TRTPN, TRTP, AVISIT, AVISITN, AVAL, BASE, CHG, DTYPE, SET) 19 | 20 | # Dataframe to merge display order of visits 21 | visits <- tibble( 22 | ORD = rep(c(1:8), 3), 23 | AVISIT = rep(c("Baseline", "Week 8 (Windowed)", "Week 16 (Windowed)", "Week 24 (Windowed)", 24 | "Week 8 LOCF", "Week 16 LOCF", "Week 24 LOCF", ''), 3), 25 | TRTPN = c(rep(c(0), 8), rep(54, 8), rep(81, 8)) 26 | ) 27 | 28 | # Join the LOCF and Windowed sets together 29 | step1 <- adas %>% 30 | bind_rows(adas %>% 31 | filter(AVISITN != 0 & DTYPE != 'LOCF') %>% 32 | mutate(SET="WINDOWED") 33 | ) %>% 34 | 35 | mutate( 36 | # Format AVISIT for display 37 | AVISIT = 38 | case_when( 39 | SET == 'WINDOWED' & AVISITN != 0 ~ paste(AVISIT, '(Windowed)'), 40 | SET == 'LOCF' & AVISITN != 0 ~ paste(AVISIT, 'LOCF'), 41 | TRUE ~ AVISIT 42 | ), 43 | # Display of TRTP 44 | TRTP = 45 | case_when( 46 | TRTPN == 0 ~ 'Placebo', 47 | TRTPN == 54 ~ 'Xan.Low', 48 | TRTPN == 81 ~ 'Xan.High' 49 | ) 50 | ) 51 | 52 | # Get all summaries for aval 53 | aval <- step1 %>% 54 | group_by(TRTPN, TRTP, AVISITN, AVISIT, SET) %>% 55 | summarize( 56 | n = num_fmt(n(), int_len=2, size=2), 57 | mean = num_fmt(mean(AVAL), digits=1, int_len=2, size=4), 58 | sd = num_fmt(sd(AVAL), digits=2, int_len=2, size=5), 59 | md = num_fmt(median(AVAL), digits=1, int_len=2, size=4), 60 | mn = num_fmt(min(AVAL), int_len=2, size=4), 61 | mx = num_fmt(max(AVAL), int_len=2, size=4), 62 | ) %>% 63 | full_join(visits, by=c("TRTPN", "AVISIT")) 64 | 65 | # Get all summaries for chg 66 | chg <- step1 %>% 67 | group_by(TRTPN, TRTP, AVISITN, AVISIT, SET) %>% 68 | filter(AVISITN != 0) %>% 69 | summarize( 70 | meanc = num_fmt(mean(CHG), digits=1, int_len=1, size=4), 71 | sdc = num_fmt(sd(CHG), digits=2, int_len=1, size=4), 72 | mdc = num_fmt(median(CHG), digits=1, int_len=1, size=4), 73 | mnc = num_fmt(min(CHG), int_len=3, size=4), 74 | mxc = num_fmt(max(CHG), int_len=2, size=4), 75 | bmn = num_fmt(mean(BASE), digits=1, int_len=2, size=4), 76 | bsd = num_fmt(sd(BASE), digits=2, int_len=2, size=5) 77 | ) 78 | 79 | # Join to AVAL and CHG results together to create final table 80 | final <- left_join(aval, chg, by=c('TRTPN', 'TRTP', 'AVISITN', 'AVISIT', 'SET')) %>% 81 | arrange(TRTPN, ORD) %>% 82 | ungroup() %>% 83 | mutate(TRTP = ifelse(ORD==1, TRTP, '')) %>% 84 | select(TRTP, AVISIT, n, mean, sd, md, mn, mx, bmn, bsd, meanc, sdc, mdc, mnc, mxc) 85 | 86 | # Create the column headers 87 | header <- tibble( 88 | TRTP=character(2), 89 | AVISIT=character(2), 90 | n=c('', 'nc'), 91 | mean=c('', 'Mean'), 92 | sd=c('', 'Std'), 93 | md=c('', 'Med.'), 94 | mn=c('', 'Min.'), 95 | mx=c('', 'Max.'), 96 | bmn=c('', 'Bsln\\line Mean'), 97 | bsd=c('', 'Bsln\\line Std'), 98 | meanc=c('---Change from baseline---', 'Mean'), 99 | sdc=c('', 'Std'), 100 | mdc=c('', 'Med.'), 101 | mnc=c('', 'Min.'), 102 | mxc=c('', 'Max.') 103 | ) 104 | 105 | # Make the table 106 | ht <- as_hux(bind_rows(header, final)) %>% 107 | huxtable::merge_cells(1, 11:15) %>% # Span header for Change from Baseline 108 | huxtable::set_bold(1:2, 1:ncol(final), TRUE) %>% # Bold the header 109 | huxtable::set_align(1:2, 1:ncol(final), 'center') %>% # Align the header 110 | huxtable::set_align(1:(nrow(final) +2), 3:ncol(final), 'center') %>% # Center all of the numeric cells 111 | huxtable::set_valign(1:2, 1:ncol(final), 'bottom') %>% # Attach the column headers to the bottom of the cell 112 | huxtable::set_bottom_border(2, 1:ncol(final), 1) %>% # Bottom border under column header 113 | huxtable::set_width(1.5) %>% # Take up the whole width of the page 114 | huxtable::set_escape_contents(FALSE) %>% # Allow RTF strings 115 | huxtable::set_col_width(c(.09, .19, .05, .06, .06, .06, .05, .05, .06, .06, .06, .05, .05, .05, .06)) # Column widths as a ratio 116 | 117 | # Write into doc object and pull titles/footnotes from excel file 118 | doc <- rtf_doc(ht, header_rows=2) %>% pharmaRTF:::titles_and_footnotes_from_df( 119 | from.file='./data/titles.xlsx', 120 | reader=example_custom_reader, 121 | table_number='14-3.10') %>% 122 | set_font_size(10) %>% 123 | set_ignore_cell_padding(TRUE) %>% 124 | set_column_header_buffer(top=1) 125 | 126 | # Write out the RTF 127 | write_rtf(doc, file='./outputs/14-3.10.rtf') 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /programs/t-14-3-11.R: -------------------------------------------------------------------------------- 1 | # t-14-3-11.R 2 | # CDISC Pilot Table 14-3.11 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | adas <- read_xpt(glue("{adam_lib}/adadas.xpt")) %>% 16 | filter(EFFFL == "Y" & PARAMCD == 'ACTOT' & ANL01FL == 'Y' & DTYPE != 'LOCF' & AVISITN > 0) 17 | 18 | # Calculate the header Ns ---- 19 | header_n <- adas %>% 20 | distinct(USUBJID, TRTP, TRTPN) %>% 21 | get_header_n(TRTP, TRTPN) 22 | 23 | column_headers <- header_n %>% 24 | select(-N) %>% 25 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 26 | mutate(rowlbl1 = '') 27 | 28 | # Gather the model data 29 | model_portion <- efficacy_models(adas, 'CHG', 24, model_type='repeated') 30 | 31 | final <- bind_rows(column_headers, model_portion) %>% 32 | select(rowlbl1, `0`, `54`, `81`) 33 | 34 | # Take off footnote references 35 | final[4,1] <- "p-value(Xan - Placebo)" 36 | final[8,1] <- "p-value(Xan High - Xan Low)" 37 | 38 | # Make the table 39 | ht <- as_hux(final) %>% 40 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 41 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 42 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 43 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 44 | huxtable::set_width(1.2) %>% 45 | huxtable::set_escape_contents(FALSE) %>% 46 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 47 | ht 48 | 49 | # Write into doc object and pull titles/footnotes from excel file 50 | doc <- rtf_doc(ht) %>% pharmaRTF:::titles_and_footnotes_from_df( 51 | from.file='./data/titles.xlsx', 52 | reader=example_custom_reader, 53 | table_number='14-3.11') %>% 54 | set_font_size(10) %>% 55 | set_ignore_cell_padding(TRUE) %>% 56 | set_column_header_buffer(top=1) 57 | 58 | # Write out the RTF 59 | write_rtf(doc, file='./outputs/14-3.11.rtf') 60 | -------------------------------------------------------------------------------- /programs/t-14-3-12.R: -------------------------------------------------------------------------------- 1 | # t-14-3-12.R 2 | # CDISC Pilot Table 14-3.12 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Read in the ADLB datasets ---- 15 | npix <- read_xpt(glue("{adam_lib}/adnpix.xpt")) %>% 16 | filter(EFFFL == 'Y' & ITTFL == 'Y' & PARAMCD == 'NPTOTMN') %>% 17 | mutate(CHG = AVAL - BASE) 18 | 19 | # Calculate the header Ns ---- 20 | header_n <- npix %>% 21 | distinct(USUBJID, TRTP, TRTPN) %>% 22 | get_header_n(TRTP, TRTPN) 23 | 24 | column_headers <- header_n %>% 25 | select(-N) %>% 26 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 27 | mutate(rowlbl1 = '') 28 | 29 | # Run each group 30 | # NOTE: The counts of Mean of Weeks 4-24 do not match the original data. This was programmed using 31 | # the derived NPTOTMN variable. Following the original analysis results metadata, as best as 32 | # I can tell, we're following the same subsetting rules. This means that the counts are a 33 | # discrepancy between the original analysis data, which is not available in the current 34 | # CDISC pilot package. The subsequent statistical summaries therefore also do not match. 35 | summary_portion <- bind_rows(summary_data(npix, AVAL, 0 , 'Baseline'), 36 | summary_data(npix, AVAL, 98, 'Mean of Weeks 4-24')) %>% 37 | pad_row() 38 | 39 | # Gather the model data 40 | model_portion <- efficacy_models(npix, 'CHG', 98) 41 | 42 | final <- bind_rows(column_headers, summary_portion, model_portion) %>% 43 | select(rowlbl1, `0`, `54`, `81`) 44 | 45 | ## Create the table 46 | 47 | # Make the table 48 | ht <- as_hux(final) %>% 49 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 50 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 51 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 52 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 53 | huxtable::set_width(1.2) %>% 54 | huxtable::set_escape_contents(FALSE) %>% 55 | huxtable::set_col_width(c(.5, 1/6, 1/6, 1/6)) 56 | ht 57 | 58 | # Write into doc object and pull titles/footnotes from excel file 59 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 60 | from.file='./data/titles.xlsx', 61 | reader=example_custom_reader, 62 | table_number='14-3.12') %>% 63 | set_font_size(10) %>% 64 | set_ignore_cell_padding(TRUE) %>% 65 | set_column_header_buffer(top=1) 66 | 67 | # Write out the RTF 68 | write_rtf(doc, file='./outputs/14-3.12.rtf') 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /programs/t-14-3-13.R: -------------------------------------------------------------------------------- 1 | # t-14-3-13.R 2 | # CDISC Pilot Table 14-3.13 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(huxtable) 9 | library(pharmaRTF) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | # Data frame for ordering and to fill 0s 15 | ord <- tibble( 16 | AVALC = rep(c('n', 17 | 'Marked improvement', 18 | 'Moderate improvement', 19 | 'Minimal improvement', 20 | 'No Change', 21 | 'Minimal worsening', 22 | 'Moderate worsening', 23 | 'Marked worsening', ''),3), 24 | ord = rep(c(0:8),3), 25 | AVISITN = c(rep(8, 9), rep(16,9), rep(24,9)), 26 | AVISIT = c(rep('Week 8', 9), rep('Week 16', 9), rep('Week 24', 9)) 27 | ) 28 | 29 | # Read in the CBIC dataset ---- 30 | cbic <- read_xpt(glue("{adam_lib}/adcibc.xpt")) %>% 31 | filter(EFFFL == 'Y' & ITTFL == 'Y', AVISITN %in% c(8, 16, 24) & ANL01FL=='Y') %>% 32 | # Create a character version of AVAL for display 33 | mutate( 34 | AVALC = ord[2:8, ]$AVALC[AVAL], # The codelist is already in this dataframe so using that 35 | ) 36 | 37 | # Calculate the header Ns ---- 38 | header_n <- cbic %>% 39 | distinct(USUBJID, TRTP, TRTPN) %>% 40 | get_header_n(TRTP, TRTPN) 41 | 42 | column_headers <- header_n %>% 43 | select(-N) %>% 44 | pivot_wider(names_from = TRTPN, values_from=labels) %>% 45 | mutate(AVISIT = '', 46 | AVALC = 'Assessment', 47 | p = 'p-value\\line [1]') 48 | 49 | # Get the summary N counts for each group 50 | ns <- cbic %>% 51 | group_by(TRTPN, AVISITN, AVISIT) %>% 52 | summarize(N = n()) %>% 53 | ungroup() 54 | 55 | counts <- cbic %>% 56 | # Summarize the categorical counts 57 | group_by(TRTPN, AVISITN, AVISIT, AVALC) %>% 58 | summarize(n = n()) %>% 59 | ungroup() %>% 60 | # Merge in the group N's for summary 61 | merge(ns, by=c('TRTPN', 'AVISITN', 'AVISIT', 'AVISIT')) %>% 62 | rowwise() %>% 63 | # Format the n (%) 64 | mutate(npct=n_pct(n, N, n_width=2)) %>% 65 | select(-n, -N) %>% 66 | # Transpose out by treatment group 67 | pivot_wider(names_from = TRTPN, values_from=npct) %>% 68 | # Bind with the N rows 69 | bind_rows( 70 | # Need for tranpose and format 71 | ns %>% 72 | rowwise() %>% 73 | # Format the N counts and add the row label 74 | mutate( 75 | AVALC = 'n', 76 | Nc = num_fmt(N, size=9, int_len=2) 77 | ) %>% 78 | select(-N) %>% 79 | # Transpose out by group 80 | pivot_wider(names_from = TRTPN, values_from=Nc) 81 | ) %>% 82 | # Join to add 0's 83 | full_join( 84 | ord, by=c('AVISITN', 'AVISIT', 'AVALC') 85 | ) %>% 86 | # Fill the 0s 87 | ## There is a bug here that causes vctrs to fail. 88 | replace_na(list(`0`=' 0 ', `54` = ' 0 ', `81`=' 0 ')) %>% 89 | # Clean up the rows that should be blank 90 | mutate( 91 | `0` = ifelse(AVALC=='', '', `0`), 92 | `54` = ifelse(AVALC=='', '', `54`), 93 | `81` = ifelse(AVALC=='', '', `81`), 94 | AVISIT = ifelse(ord==0, AVISIT, '') 95 | ) %>% 96 | # Sort 97 | arrange(AVISITN, ord) 98 | 99 | 100 | ## P-values ---- 101 | # !!! NOTE: To obtain the same p-value used in SAS for this display, a modification had to be made to the vcdExtra library. 102 | # Please refer to this github issue: https://github.com/friendly/vcdExtra/issues/3 103 | # And you can access our fork of the library here: https://github.com/mstackhouse/vcdExtra 104 | counts['p'] <- character(nrow(counts)) 105 | 106 | counts[(counts$AVISITN==8 & counts$ord==0),'p'] <- cbic %>% 107 | filter(AVISITN == 8) %>% 108 | cmh_p(AVAL ~ TRTP | SITEGR1) %>% 109 | num_fmt(digits=4, size=5, int_len=1) 110 | 111 | counts[(counts$AVISITN==16 & counts$ord==0),'p'] <- cbic %>% 112 | filter(AVISITN == 16) %>% 113 | cmh_p(AVAL ~ TRTP | SITEGR1) %>% 114 | num_fmt(digits=4, size=5, int_len=1) 115 | 116 | counts[(counts$AVISITN==24 & counts$ord==0),'p'] <- cbic %>% 117 | filter(AVISITN == 24) %>% 118 | cmh_p(AVAL ~ TRTP | SITEGR1) %>% 119 | num_fmt(digits=4, size=5, int_len=1) 120 | 121 | final <- bind_rows(column_headers, counts) %>% 122 | select(AVISIT, AVALC, `0`,`54`,`81`, p) 123 | 124 | ## Create the table 125 | 126 | # Make the table 127 | ht <- as_hux(final) %>% 128 | huxtable::set_bold(1, 1:ncol(final), TRUE) %>% 129 | huxtable::set_align(1, 1:ncol(final), 'center') %>% 130 | huxtable::set_align(1,2, 'left') %>% 131 | huxtable::set_valign(1, 1:ncol(final), 'bottom') %>% 132 | huxtable::set_bottom_border(1, 1:ncol(final), 1) %>% 133 | huxtable::set_width(1.2) %>% 134 | huxtable::set_escape_contents(FALSE) %>% 135 | huxtable::set_col_width(c(1/8, 3/8, 1/8, 1/8, 1/8, 1/8)) 136 | ht 137 | 138 | # Write into doc object and pull titles/footnotes from excel file 139 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 140 | from.file='./data/titles.xlsx', 141 | reader=example_custom_reader, 142 | table_number='14-3.13') %>% 143 | set_font_size(10) %>% 144 | set_ignore_cell_padding(TRUE) %>% 145 | set_column_header_buffer(top=1) 146 | 147 | # Write out the RTF 148 | write_rtf(doc, file='./outputs/14-3.13.rtf') 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /programs/t-14-4-01.R: -------------------------------------------------------------------------------- 1 | # t-14-4-01.R 2 | # CDISC Pilot Table 14-4.01 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(pharmaRTF) 9 | 10 | source('./programs/config.R') 11 | source('./programs/funcs.R') 12 | 13 | # Read in ADSL 14 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 15 | 16 | # Subset for completers 17 | adsl_complt <- adsl %>% 18 | filter(COMP24FL == 'Y') %>% 19 | select(TRT01P, TRT01PN, AVGDD, CUMDOSE) %>% 20 | mutate(cat = 1, TRTPCD = paste(TRT01PN, '_C', sep='')) 21 | 22 | # Subset for safety 23 | adsl_safety <- adsl %>% 24 | filter(SAFFL == 'Y') %>% 25 | select(TRT01P, TRT01PN, AVGDD, CUMDOSE) %>% 26 | mutate(cat = 2, TRTPCD = paste(TRT01PN, '_S', sep='')) 27 | 28 | # Stack the two together 29 | adsl_ = bind_rows(adsl_safety, adsl_complt) 30 | rm(adsl_safety, adsl_complt) # Clean-up 31 | 32 | # Header N counts and column headers 33 | header <- adsl_ %>% 34 | group_by(TRTPCD, TRT01P, TRT01PN, cat) %>% 35 | summarize(N = n()) %>% 36 | mutate( 37 | labels = str_replace_all(str_wrap(glue('{TRT01P} (N={N})'), width=10), "\n", function(x) "\\line ") 38 | ) %>% 39 | ungroup() %>% 40 | arrange(cat, TRT01PN) %>% 41 | select(TRTPCD, labels) %>% 42 | pivot_wider(names_from=TRTPCD, values_from=labels) 43 | 44 | # Calculate average daily dose summary stats 45 | avgdd <- adsl_ %>% desc_stats(AVGDD, group=TRTPCD, int_len=5) %>% 46 | mutate(rowlbl1 = 'Average daily dose (mg)') 47 | 48 | # Calculate cumulative dose at end of study 49 | cumdose <- adsl_ %>% desc_stats(CUMDOSE, group=TRTPCD, int_len=5) %>% 50 | mutate(rowlbl1 = 'Cumulative dose at end of study [2]') 51 | 52 | # Spanner - want this to be the top left cell of the cells that will merge 53 | spanner <- tibble(`0_C` = 'Completers at Week 24', `0_S` = 'Safety Population [1]') 54 | 55 | # Join it all together, order columns, clean grouped cells 56 | final <- bind_rows(spanner, header, avgdd, cumdose) %>% 57 | select(rowlbl1, rowlbl2, `0_C`, `54_C`, `81_C`, `0_S`, `54_S`, `81_S`) %>% 58 | group_by(rowlbl1) %>% 59 | mutate(ord1 = row_number()) %>% 60 | ungroup() %>% 61 | mutate(rowlbl1 = ifelse(ord1 == 1, rowlbl1, "")) %>% 62 | select(-ord1) 63 | 64 | ht <- huxtable::as_hux(final) %>% 65 | huxtable::merge_cells(1, 3:5) %>% 66 | huxtable::merge_cells(1, 6:8) 67 | huxtable::bottom_border(ht)[1, 3] <- 1 68 | huxtable::bottom_border(ht)[1, 6] <- 1 69 | huxtable::bottom_border(ht)[2, ] <- 1 70 | huxtable::valign(ht)[1:2, ] <- 'bottom' 71 | huxtable::bold(ht)[1:2, ] <- TRUE 72 | huxtable::align(ht)[1:2, ] <- 'center' 73 | huxtable::width(ht) <- 1.5 74 | huxtable::escape_contents(ht) <- FALSE 75 | huxtable::col_width(ht) <- c(.36, .07, .1, .11, .11, .1, .11, .11) 76 | huxtable::bottom_padding(ht) <- 0 77 | huxtable::top_padding(ht) <- 0 78 | 79 | # Write into doc object and pull titles/footnotes from excel file 80 | doc <- rtf_doc(ht, header_rows = 2) %>% titles_and_footnotes_from_df( 81 | from.file='./data/titles.xlsx', 82 | reader=example_custom_reader, 83 | table_number='14-4.01') %>% 84 | set_column_header_buffer(top=1) %>% 85 | set_font_size(10) 86 | 87 | # Write out the RTF 88 | write_rtf(doc, file='./outputs/14-4.01.rtf') 89 | -------------------------------------------------------------------------------- /programs/t-14-5-01.R: -------------------------------------------------------------------------------- 1 | # t-14-5-01.R 2 | # CDISC Pilot Table 14-5.01 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(pharmaRTF) 8 | 9 | source('./programs/config.R') 10 | source('./programs/funcs.R') 11 | 12 | # Read in ADSL 13 | adae <- read_xpt(glue("{adam_lib}/adae.xpt")) %>% 14 | filter(SAFFL == 'Y' & TRTEMFL == 'Y') 15 | 16 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 17 | 18 | # Header N ---- 19 | header_n <- adsl %>% 20 | get_header_n() 21 | 22 | # Overall counts 23 | overall <- ae_counts(adae, N_counts = header_n) %>% 24 | mutate(AETERM = 'ANY BODY SYSTEM', AEBODSYS = 'ANY BODY SYSTEM', ord1=1, ord2=1) 25 | 26 | # System Organ Class counts 27 | bodsys <- ae_counts(adae, AEBODSYS, N_counts = header_n) %>% 28 | mutate(AETERM = AEBODSYS, ord1=2, ord2=1) %>% 29 | arrange(AEBODSYS) 30 | 31 | pad <- bodsys %>% 32 | select(AEBODSYS, ord1, ord2) %>% 33 | mutate(ord3=999) 34 | 35 | # Individual term counts 36 | term <- ae_counts(adae, AEBODSYS, AETERM, sort=TRUE, N_counts = header_n) %>% 37 | mutate(AETERM = paste0(' ', AETERM), ord1=2, ord2=2) 38 | 39 | # Bring the data together 40 | combined <- bind_rows(overall, bodsys, pad, term) %>% 41 | arrange(ord1, AEBODSYS, ord2, desc(ord3), AETERM) 42 | 43 | # Build and attach column headers 44 | column_headers <- header_n %>% 45 | select(-N) %>% 46 | pivot_wider(names_from = TRT01PN, values_from=labels) %>% 47 | select(npct_0=`0`, npct_54=`54`, npct_81=`81`) %>% 48 | mutate(cAEs_0 = '', 49 | cAEs_54 = '', 50 | cAEs_81 = '', 51 | AETERM = '', 52 | p_low = "Fisher's Exact\\line p-values", 53 | p_high = '') 54 | 55 | # Insert second row of header 56 | column_headers <- bind_rows(column_headers, tibble( 57 | AETERM = 'System Organ Class/\\line Preferred Term', 58 | npct_0 = 'n(%)', 59 | cAEs_0 = '[AEs]', 60 | npct_54 = 'n(%)', 61 | cAEs_54 = '[AEs]', 62 | npct_81 = 'n(%)', 63 | cAEs_81 = '[AEs]', 64 | p_low = 'Placebo\\line vs.\\line Low Dose', 65 | p_high = 'Placebo\\line vs.\\line High Dose' 66 | )) 67 | 68 | # Attach to final 69 | final <- bind_rows(column_headers, combined) %>% 70 | select(AETERM, npct_0, cAEs_0, npct_54, cAEs_54, npct_81, cAEs_81, p_low, p_high) 71 | 72 | 73 | # Make the table ---- 74 | 75 | ht <- huxtable::as_hux(final) %>% 76 | huxtable::merge_cells(1, 2:3) %>% 77 | huxtable::merge_cells(1, 4:5) %>% 78 | huxtable::merge_cells(1, 6:7) %>% 79 | huxtable::merge_cells(1, 8:9) 80 | huxtable::bottom_border(ht)[2, ] <- 1 81 | huxtable::valign(ht)[1:2, ] <- 'bottom' 82 | huxtable::bold(ht)[1:2, ] <- TRUE 83 | huxtable::align(ht)[1:2, ] <- 'center' 84 | huxtable::width(ht) <- 1.5 85 | huxtable::escape_contents(ht) <- FALSE 86 | huxtable::col_width(ht) <- c(.3, .1, .07, .1, .07, .1, .07, .09, .1) 87 | huxtable::bottom_padding(ht) <- 0 88 | huxtable::top_padding(ht) <- 0 89 | # ht 90 | 91 | # Write into doc object and pull titles/footnotes from excel file 92 | doc <- rtf_doc(ht, header_rows = 2) %>% titles_and_footnotes_from_df( 93 | from.file='./data/titles.xlsx', 94 | reader=example_custom_reader, 95 | table_number='14-5.01') %>% 96 | set_font_size(10) %>% 97 | set_ignore_cell_padding(TRUE) %>% 98 | set_column_header_buffer(top=1) 99 | 100 | # Write out the RTF 101 | write_rtf(doc, file='./outputs/14-5.01.rtf') 102 | -------------------------------------------------------------------------------- /programs/t-14-5-02.R: -------------------------------------------------------------------------------- 1 | # t-14-5-02.R 2 | # CDISC Pilot Table 14-5.02 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(pharmaRTF) 8 | 9 | source('./programs/config.R') 10 | source('./programs/funcs.R') 11 | 12 | # Read in ADSL and ADAE 13 | adae <- read_xpt(glue("{adam_lib}/adae.xpt")) %>% 14 | filter(SAFFL == 'Y' & TRTEMFL == 'Y' & AESER == 'Y') 15 | 16 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 17 | 18 | # Header N ---- 19 | header_n <- adsl %>% 20 | get_header_n() 21 | 22 | # Overall counts 23 | overall <- ae_counts(adae, N_counts = header_n) %>% 24 | mutate(AETERM = 'ANY BODY SYSTEM', AEBODSYS = 'ANY BODY SYSTEM', ord1=1, ord2=1) 25 | 26 | # System Organ Class counts 27 | bodsys <- ae_counts(adae, AEBODSYS, N_counts = header_n) %>% 28 | mutate(AETERM = AEBODSYS, ord1=2, ord2=1) %>% 29 | arrange(AEBODSYS) 30 | 31 | pad <- bodsys %>% 32 | select(AEBODSYS, ord1, ord2) %>% 33 | mutate(ord3=999) 34 | 35 | # Individual term counts 36 | term <- ae_counts(adae, AEBODSYS, AETERM, sort=TRUE, N_counts = header_n) %>% 37 | mutate(AETERM = paste0(' ', AETERM), ord1=2, ord2=2) 38 | 39 | # Bring the data together 40 | combined <- bind_rows(overall, bodsys, pad, term) %>% 41 | arrange(ord1, AEBODSYS, ord2, desc(ord3), AETERM) 42 | 43 | # Build and attach column headers 44 | column_headers <- header_n %>% 45 | select(-N) %>% 46 | pivot_wider(names_from = TRT01PN, values_from=labels) %>% 47 | select(npct_0=`0`, npct_54=`54`, npct_81=`81`) %>% 48 | mutate(cAEs_0 = '', 49 | cAEs_54 = '', 50 | cAEs_81 = '', 51 | AETERM = '', 52 | p_low = "Fisher's Exact\\line p-values", 53 | p_high = '') 54 | 55 | # Insert second row of header 56 | column_headers <- bind_rows(column_headers, tibble( 57 | AETERM = 'System Organ Class/\\line Preferred Term', 58 | npct_0 = 'n(%)', 59 | cAEs_0 = '[AEs]', 60 | npct_54 = 'n(%)', 61 | cAEs_54 = '[AEs]', 62 | npct_81 = 'n(%)', 63 | cAEs_81 = '[AEs]', 64 | p_low = 'Placebo\\line vs.\\line Low Dose', 65 | p_high = 'Placebo\\line vs.\\line High Dose' 66 | )) 67 | 68 | # Attach to final 69 | final <- bind_rows(column_headers, combined) %>% 70 | select(AETERM, npct_0, cAEs_0, npct_54, cAEs_54, npct_81, cAEs_81, p_low, p_high) 71 | 72 | # Make the table ---- 73 | 74 | ht <- huxtable::as_hux(final) %>% 75 | huxtable::merge_cells(1, 2:3) %>% 76 | huxtable::merge_cells(1, 4:5) %>% 77 | huxtable::merge_cells(1, 6:7) %>% 78 | huxtable::merge_cells(1, 8:9) 79 | huxtable::bottom_border(ht)[2, ] <- 1 80 | huxtable::valign(ht)[1:2, ] <- 'bottom' 81 | huxtable::bold(ht)[1:2, ] <- TRUE 82 | huxtable::align(ht)[1:2, ] <- 'center' 83 | huxtable::width(ht) <- 1.5 84 | huxtable::escape_contents(ht) <- FALSE 85 | huxtable::col_width(ht) <- c(.3, .1, .07, .1, .07, .1, .07, .09, .1) 86 | huxtable::bottom_padding(ht) <- 0 87 | huxtable::top_padding(ht) <- 0 88 | # ht 89 | 90 | # Write into doc object and pull titles/footnotes from excel file 91 | doc <- rtf_doc(ht, header_rows = 2) %>% titles_and_footnotes_from_df( 92 | from.file='./data/titles.xlsx', 93 | reader=example_custom_reader, 94 | table_number='14-5.02') %>% 95 | set_font_size(10) %>% 96 | set_ignore_cell_padding(TRUE) %>% 97 | set_column_header_buffer(top=1) 98 | 99 | # Write out the RTF 100 | write_rtf(doc, file='./outputs/14-5.02.rtf') 101 | -------------------------------------------------------------------------------- /programs/t-14-6-01.R: -------------------------------------------------------------------------------- 1 | # t-14-6-01.R 2 | # CDISC Pilot Table 14-4.01 3 | 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(pharmaRTF) 9 | 10 | source('./programs/config.R') 11 | source('./programs/funcs.R') 12 | 13 | # Read in the ADLB datasets 14 | adlbc <- read_xpt(glue("{adam_lib}/adlbc.xpt")) %>% 15 | filter(SAFFL == 'Y' & (AVISITN != 99 | (AVISITN == 99 & AENTMTFL=='Y'))) 16 | 17 | adlbc$PARAM<- recode(adlbc$PARAM, 18 | "Alanine Aminotransferase (U/L)" = "ALANINE AMINOTRANSFERASE", 19 | "Albumin (g/L)" = "ALBUMIN", 20 | "Alkaline Phosphatase (U/L)" = "ALKALINE PHOSPHATASE", 21 | "Aspartate Aminotransferase (U/L)" = "ASPARTATE AMINOTRANSFERASE", 22 | "Bilirubin (umol/L)" = "BILIRUBIN", 23 | "Calcium (mmol/L)" = "CALCIUM", 24 | "Chloride (mmol/L)" = "CHLORIDE", 25 | "Cholesterol (mmol/L)" = "CHOLESTEROL", 26 | "Creatine Kinase (U/L)" = "CREATINE KINASE", 27 | "Creatinine (umol/L)" = "CREATININE", 28 | "Gamma Glutamyl Transferase (U/L)" = "GAMMA GLUTAMYL TRANSFERASE", 29 | "Glucose (mmol/L)" = "GLUCOSE", 30 | "Phosphate (mmol/L)" = "PHOSPHATE", 31 | "Potassium (mmol/L)" = "POTASSIUM", 32 | "Protein (g/L)" = "PROTEIN", 33 | "Sodium (mmol/L)" = "SODIUM", 34 | "Urate (umol/L)" = "URATE", 35 | "Blood Urea Nitrogen (mmol/L)" = "UREA NITROGEN") 36 | 37 | adlbh <- read_xpt(glue("{adam_lib}/adlbh.xpt")) %>% 38 | filter(SAFFL == 'Y' & !(PARAM %in% c('Anisocytes', 'Poikilocytes', 'Microcytes', 'Macrocytes', 'Polychromasia')) 39 | & (AVISITN != 99 | (AVISITN == 99 & AENTMTFL=='Y'))) 40 | 41 | adlbh$PARAM<- recode(adlbh$PARAM, 42 | "Basophils (GI/L)" = "BASOPHILS", 43 | "Eosinophils (GI/L)" = "EOSINOPHILS", 44 | "Ery. Mean Corpuscular HGB Concentration (mmol/L)" = "ERY. MEAN CORPUSCULAR HB CONCENTRATION", 45 | "Ery. Mean Corpuscular Hemoglobin (fmol(Fe))" = "ERY. MEAN CORPUSCULAR HEMOGLOBIN", 46 | "Ery. Mean Corpuscular Volume (fL)" = "ERY. MEAN CORPUSCULAR VOLUME", 47 | "Erythrocytes (TI/L)" = "ERYTHROCYTES", 48 | "Hematocrit" = "HEMATOCRIT", 49 | "Hemoglobin (mmol/L)" = "HEMOGLOBIN", 50 | "Leukocytes (GI/L)" = "LEUKOCYTES", 51 | "Lymphocytes (GI/L)" = "LYMPHOCYTES", 52 | "Monocytes (GI/L)" = "MONOCYTES", 53 | "Platelet (GI/L)" = "PLATELET") 54 | 55 | # Template for assigning display visit values 56 | visit_names <- data.frame( 57 | AVISITN = c(0, 2, 4, 6, 8, 12, 16, 20, 24, 26, 99), 58 | AVISIT = c(" Bsln", " Wk 2", " Wk 4", " Wk 6", " Wk 8", " Wk 12", 59 | " Wk 16", " Wk 20", " Wk 24", " Wk 26", " End[1]"), 60 | stringsAsFactors = FALSE 61 | ) 62 | 63 | test_summary <- function(x, df_=NULL) { 64 | # Build up the visit table and attach on the end visit (using flag) 65 | visits <- df_ %>% 66 | # Filter to the specified test 67 | filter(AVISIT != 'UNSCHEDULED' & PARAM == x) 68 | 69 | # Summarize results by visit and treatment 70 | res <- visits %>% 71 | group_by(AVISITN, TRTPN) %>% 72 | summarize(n = n(), 73 | mean_res = mean(AVAL, na.rm=TRUE), 74 | sd_res = sd(AVAL, na.rm=TRUE)) 75 | 76 | # Summarize change from baseline by visit and treatment 77 | chgbl <- visits %>% 78 | filter(AVISITN != 1) %>% 79 | group_by(AVISITN, TRTPN) %>% 80 | summarize(mean_cbl = mean(CHG, na.rm=TRUE), 81 | sd_cbl = sd(CHG, na.rm=TRUE)) 82 | 83 | # Build the display string 84 | df <- merge(res, chgbl, by = c('AVISITN', 'TRTPN'), all=TRUE) %>% 85 | rowwise() %>% 86 | mutate( 87 | N = 88 | ifelse( 89 | !is.na(n), 90 | num_fmt(n, size=2, int_len=2), 91 | ''), 92 | msr = 93 | ifelse( 94 | !is.na(mean_res), 95 | as.character(glue('{num_fmt(mean_res, size=5, digits=1, int_len=3)} ({num_fmt(sd_res, size=6, digits=2, int_len=3)})')), 96 | ''), 97 | msc = 98 | ifelse( 99 | !is.na(mean_cbl), 100 | as.character(glue('{num_fmt(mean_cbl, size=5, digits=1, int_len=3)} ({num_fmt(sd_cbl, size=6, digits=2, int_len=3)})')), 101 | '') 102 | ) %>% 103 | # Transpose the treatments out 104 | select(AVISITN, TRTPN, N, msr, msc) %>% 105 | pivot_wider(names_from = TRTPN, values_from = c(N, msr, msc)) %>% 106 | # Merge in the visits 107 | merge(visit_names, by='AVISITN') %>% 108 | arrange(AVISITN) %>% 109 | select(AVISIT, N_0, msr_0, msc_0, N_54, msr_54, msc_54, N_81, msr_81, msc_81) %>% 110 | pad_row() 111 | 112 | # Stub header 113 | stub_head = data.frame(AVISIT = x, stringsAsFactors = FALSE) 114 | 115 | final <- bind_rows(stub_head, df) 116 | ht <- huxtable::as_hux(final) %>% 117 | huxtable::merge_cells(1, 1:5) 118 | ht 119 | 120 | } 121 | 122 | add_group_head <- function(ht, group) { 123 | # Make a three row subset to grab names 124 | head_ <- ht[1:3, ] 125 | # Blank everything out 126 | head_[,] <- '' 127 | # First value is the group label 128 | head_[1, 1] <- group 129 | # Merge the cells 130 | head_ <- huxtable::merge_cells(head_, 1, 1:5) 131 | # Bind to the table 132 | rbind(head_, ht) 133 | } 134 | 135 | # Summarize all the chemistry data 136 | chem <- do.call(rbind, lapply(sort(unique(adlbc$PARAM)), test_summary, df_=adlbc)) %>% 137 | add_group_head('CHEMISTRY') 138 | 139 | # Summarize all the hematology data 140 | hema <- do.call(rbind, lapply(sort(unique(adlbh$PARAM)), test_summary, df_=adlbh)) %>% 141 | add_group_head('HEMATOLOGY') 142 | 143 | # Bind those two 144 | ht <- rbind(chem, hema) 145 | 146 | # Make the column headers 147 | col_headers <- ht[5:6, ] # Stealing out a chunk of the table with no cell merging 148 | col_headers[1, ] <- c('', 'Placebo', '', '', 'Xanomeline Low', '', '', 'Xanomeline High', '', '') 149 | col_headers[2, ] <- c('Visit', 'N', 'Mean (SD)', 'Change\\line from Bsln\\line Mean (SD)', 150 | 'N', 'Mean (SD)', 'Change\\line from Bsln\\line Mean (SD)', 151 | 'N', 'Mean (SD)', 'Change\\line from Bsln\\line Mean (SD)') 152 | 153 | # Now 154 | col_headers <- col_headers %>% 155 | # Placebo spanner 156 | huxtable::merge_cells(1, 2:4) %>% 157 | huxtable::set_bottom_border(1, 2:4, 1) %>% 158 | huxtable::set_bottom_border_style(1, 2:4, 'dashed') %>% 159 | # Xanomeline Low spanner 160 | huxtable::merge_cells(1, 5:7) %>% 161 | huxtable::set_bottom_border(1, 5:7, 1) %>% 162 | huxtable::set_bottom_border_style(1, 5:7, 'dashed') %>% 163 | # Xanomeline High spanner 164 | huxtable::merge_cells(1, 8:10) %>% 165 | huxtable::set_bottom_border(1, 8:10, 1) %>% 166 | huxtable::set_bottom_border_style(1, 8:10, 'dashed') %>% 167 | # Bottom border 168 | huxtable::set_bottom_border(2, 1:10, value=1) %>% 169 | # bold it all 170 | huxtable::set_bold(value=TRUE) %>% 171 | huxtable::set_align(value='center') %>% 172 | huxtable::set_valign(value='bottom') 173 | 174 | final <- rbind(col_headers, ht) %>% 175 | huxtable::set_width(1.5) %>% 176 | huxtable::set_escape_contents(FALSE) %>% 177 | huxtable::set_col_width(1:10, value=c(.1, .03, .14, .14, .03, .14, .14, .03, .14, .14)) %>% 178 | huxtable::set_bottom_padding(0) %>% 179 | huxtable::set_top_padding(0) 180 | 181 | # Write into doc object and pull titles/footnotes from excel file 182 | doc <- rtf_doc(final, header_rows = 2) %>% titles_and_footnotes_from_df( 183 | from.file='./data/titles.xlsx', 184 | reader=example_custom_reader, 185 | table_number='14-6.01') %>% 186 | set_font_size(10) %>% 187 | set_ignore_cell_padding(TRUE) %>% 188 | set_column_header_buffer(top=1) 189 | 190 | # Write out the RTF 191 | write_rtf(doc, file='./outputs/14-6.01.rtf') 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /programs/t-14-6.02.R: -------------------------------------------------------------------------------- 1 | ## Table 14-6.02 Frequency of Normal and Abnormal (Beyond Normal Range) Laboratory Values During Treatment 2 | 3 | library(huxtable) 4 | library(dplyr) 5 | library(glue) 6 | library(tidyverse) 7 | library(haven) 8 | library(pharmaRTF) 9 | library(tibble) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | n_pct <- function(n, pct, n_width=3, pct_width=3) { 15 | n <- unlist(n) 16 | pct <- unique(pct) 17 | # n (%) formatted string. e.g. 50 ( 75%) 18 | unlist(lapply(n, function(x) { 19 | if(x == 0) " 0 " 20 | else { 21 | as.character( 22 | # Form the string using glue and format 23 | glue('{format(x, width=n_width)}({format(round((x/pct) * 100), width=pct_width)}%)') 24 | ) 25 | } 26 | })) 27 | } 28 | 29 | ## Chem 30 | adlbc <- read_xpt(glue("{adam_lib}/adlbc.xpt")) %>% 31 | filter(SAFFL == "Y", ANL01FL == "Y", AVISITN != 99) 32 | 33 | adlbc$TRTP <- ordered(adlbc$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 34 | adlbc$PARAM<- recode(adlbc$PARAM, 35 | "Alanine Aminotransferase (U/L)" = "ALANINE AMINOTRANSFERASE", 36 | "Albumin (g/L)" = "ALBUMIN", 37 | "Alkaline Phosphatase (U/L)" = "ALKALINE PHOSPHATASE", 38 | "Aspartate Aminotransferase (U/L)" = "ASPARTATE AMINOTRANSFERASE", 39 | "Bilirubin (umol/L)" = "BILIRUBIN", 40 | "Calcium (mmol/L)" = "CALCIUM", 41 | "Chloride (mmol/L)" = "CHLORIDE", 42 | "Cholesterol (mmol/L)" = "CHOLESTEROL", 43 | "Creatine Kinase (U/L)" = "CREATINE KINASE", 44 | "Creatinine (umol/L)" = "CREATININE", 45 | "Gamma Glutamyl Transferase (U/L)" = "GAMMA GLUTAMYL TRANSFERASE", 46 | "Glucose (mmol/L)" = "GLUCOSE", 47 | "Phosphate (mmol/L)" = "PHOSPHATE", 48 | "Potassium (mmol/L)" = "POTASSIUM", 49 | "Protein (g/L)" = "PROTEIN", 50 | "Sodium (mmol/L)" = "SODIUM", 51 | "Urate (umol/L)" = "URATE", 52 | "Blood Urea Nitrogen (mmol/L)" = "UREA NITROGEN") 53 | #sort tests 54 | adlbc$PARAM <-ordered(adlbc$PARAM, c( 55 | "ALBUMIN", 56 | "ALKALINE PHOSPHATASE", 57 | "ALANINE AMINOTRANSFERASE", 58 | "ASPARTATE AMINOTRANSFERASE", 59 | "BILIRUBIN", 60 | "UREA NITROGEN", 61 | "CALCIUM", 62 | "CHOLESTEROL", 63 | "CREATINE KINASE", 64 | "CHLORIDE", 65 | "CREATININE", 66 | "GAMMA GLUTAMYL TRANSFERASE", 67 | "GLUCOSE", 68 | "POTASSIUM", 69 | "SODIUM", 70 | "PHOSPHATE", 71 | "PROTEIN", 72 | "URATE" 73 | )) 74 | adlbc$LBNRIND <- recode(adlbc$LBNRIND, 75 | "LOW" = "L", 76 | "NORMAL" = "N", 77 | "HIGH" = "H") 78 | adlbc$LBNRIND <- ordered(adlbc$LBNRIND, c("L", "N", "H")) 79 | 80 | 81 | adlbc2 <- adlbc %>% 82 | filter(!is.na(PARAM), !is.na(TRTP), !is.na(LBNRIND)) %>% 83 | filter(LBNRIND %in% c("L", "N", "H")) %>% 84 | group_by(PARAM, TRTP, LBNRIND) %>% 85 | complete(nesting(PARAM, TRTP, LBNRIND)) %>% 86 | summarise(N = n()) %>% 87 | group_by(PARAM, TRTP) %>% 88 | mutate(tot = sum(N)) %>% 89 | arrange(PARAM, TRTP) 90 | 91 | adlbc_pvals <- c() 92 | 93 | for(i in seq(nrow(adlbc2)/9)) { 94 | adlbc_pvals[i] <- round(fisher.test( 95 | matrix(unlist(adlbc2[((i-1)*9+1):(i*9), "N"]), nrow = 3, ncol = 3, byrow = FALSE) 96 | )$p.value, 3) 97 | } 98 | 99 | adlbc3 <- adlbc2 %>% 100 | mutate(n_w_pct = n_pct(N, tot, n_width = 2)) %>% 101 | pivot_wider(id_cols = PARAM,names_from = c(TRTP, LBNRIND), values_from = n_w_pct) %>% 102 | add_column("p-val\\line [1]" = num_fmt(unlist(adlbc_pvals), size = 4, digits = 3, int_len = 1)) 103 | 104 | ### Heme 105 | adlbh <- read_xpt(glue("{adam_lib}/adlbh.xpt")) %>% 106 | filter(SAFFL == "Y", ANL01FL == "Y", AVISITN != 99) 107 | 108 | adlbh$TRTP <- ordered(adlbh$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 109 | adlbh$PARAM<- recode(adlbh$PARAM, 110 | "Basophils (GI/L)" = "BASOPHILS", 111 | "Eosinophils (GI/L)" = "EOSINOPHILS", 112 | "Ery. Mean Corpuscular HGB Concentration (mmol/L)" = "ERY. MEAN CORPUSCULAR HB CONCENTRATION", 113 | "Ery. Mean Corpuscular Hemoglobin (fmol(Fe))" = "ERY. MEAN CORPUSCULAR HEMOGLOBIN", 114 | "Ery. Mean Corpuscular Volume (fL)" = "ERY. MEAN CORPUSCULAR VOLUME", 115 | "Erythrocytes (TI/L)" = "ERYTHROCYTES", 116 | "Hematocrit" = "HEMATOCRIT", 117 | "Hemoglobin (mmol/L)" = "HEMOGLOBIN", 118 | "Leukocytes (GI/L)" = "LEUKOCYTES", 119 | "Lymphocytes (GI/L)" = "LYMPHOCYTES", 120 | "Monocytes (GI/L)" = "MONOCYTES", 121 | "Platelet (GI/L)" = "PLATELET") 122 | #sort tests 123 | adlbh$PARAM <-ordered(adlbh$PARAM, c( 124 | "BASOPHILS", 125 | "EOSINOPHILS", 126 | "HEMATOCRIT", 127 | "HEMOGLOBIN", 128 | "LYMPHOCYTES", 129 | "ERY. MEAN CORPUSCULAR HEMOGLOBIN", 130 | "ERY. MEAN CORPUSCULAR HB CONCENTRATION", 131 | "ERY. MEAN CORPUSCULAR VOLUME", 132 | "MONOCYTES", 133 | "PLATELET", 134 | "ERYTHROCYTES", 135 | "LEUKOCYTES")) 136 | adlbh$LBNRIND <- recode(adlbh$LBNRIND, 137 | "LOW" = "L", 138 | "NORMAL" = "N", 139 | "HIGH" = "H") 140 | adlbh$LBNRIND <- ordered(adlbh$LBNRIND, c("L", "N", "H")) 141 | 142 | 143 | adlbh2 <- adlbh %>% 144 | filter(LBNRIND %in% c("L", "N", "H")) %>% 145 | group_by(PARAM, TRTP, LBNRIND) %>% 146 | complete(nesting(PARAM, TRTP, LBNRIND)) %>% 147 | summarise(N = n()) %>% 148 | group_by(PARAM, TRTP) %>% 149 | mutate(tot = sum(N)) 150 | 151 | adlbh_pvals <- c() 152 | 153 | #Some differences between SAS an R algorithms 154 | for(i in seq(nrow(adlbh2)/9)) { 155 | mat <- matrix(unlist(adlbh2[((i-1)*9+1):(i*9), "N"]), nrow = 3, ncol = 3, byrow = TRUE) 156 | if(all(mat[,1] == 0) & all(mat[,3] == 0)) { 157 | adlbh_pvals[i] <- as.numeric(NA) 158 | } else { 159 | adlbh_pvals[i] <- num_fmt(round(fisher.test(mat)$p.value, 3), size = 4, digits = 3, int_len = 1) 160 | } 161 | } 162 | 163 | adlbh3 <- adlbh2 %>% 164 | mutate(n_w_pct = n_pct(N, tot, n_width = 2)) %>% 165 | pivot_wider(id_cols = PARAM,names_from = c(TRTP, LBNRIND), values_from = n_w_pct) %>% 166 | add_column("p-val\\line [1]" = unlist(adlbh_pvals)) 167 | 168 | final <- adlbc3 %>% 169 | ungroup() %>% 170 | add_row("PARAM" = "----------", .before = 1) %>% 171 | add_row("PARAM" = "CHEMISTRY", .before = 1) %>% 172 | add_row("PARAM" = "", .before = 1) %>% 173 | add_row("PARAM" = "") %>% 174 | add_row("PARAM" = "HEMATOLOGY") %>% 175 | add_row("PARAM" = "----------") %>% 176 | rbind(ungroup(adlbh3)) 177 | 178 | 179 | names(final) <- c( 180 | "", 181 | "Low", 182 | "Normal", 183 | "High", 184 | "Low", 185 | "Normal", 186 | "High", 187 | "Low", 188 | "Normal", 189 | "High", 190 | "p-val\\line[1]" 191 | ) 192 | 193 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 194 | headers <- adsl %>% 195 | filter(ARM != "Screen Failure") %>% 196 | group_by(ARM) %>% 197 | summarise(N = n()) %>% 198 | mutate(label = paste0(recode(ARM, 199 | "Placebo" = "Placebo", 200 | "Xanomeline Low Dose" = "Xan. Low", 201 | "Xanomeline High Dose" = "Xan. High"), " (N=", N, ")")) 202 | pad_row <- function(df, r) { 203 | #df - dataframe to insert pad 204 | #r - row number to pad 205 | for(i in seq(along = r)) { 206 | if(r[i] + i - 1 < nrow(df)){ 207 | df[seq(r[i] + i, nrow(df) + 1),] <- df[seq(r[i] + (i - 1), nrow(df)),] 208 | df[r[i] + (i - 1),] <- NA 209 | } else { 210 | df[r[i] + (i - 1),] <- NA 211 | } 212 | } 213 | df 214 | } 215 | 216 | ht <- final %>% 217 | as_huxtable(add_colnames = TRUE) 218 | 219 | ht <- as_hux(pad_row(as.data.frame(ht), c(1,1)), add_colnames = FALSE) 220 | ht[1, 2] <- headers[1, "label"] 221 | ht[1, 5] <- headers[3, "label"] 222 | ht[1, 8] <- headers[2, "label"] 223 | 224 | ht2 <- ht %>% 225 | huxtable::merge_cells(1, 2:4) %>% 226 | huxtable::merge_cells(1, 5:7) %>% 227 | huxtable::merge_cells(1, 8:10) %>% 228 | huxtable::set_bottom_border(2, 2:4, 1) %>% 229 | huxtable::set_bottom_border(2, 5:7, 1) %>% 230 | huxtable::set_bottom_border(2, 8:10, 1) %>% 231 | huxtable::set_bottom_border(3, 1:11, 1) %>% 232 | huxtable::set_col_width(1:11, c(0.18, rep(0.082, 10))) %>% 233 | huxtable::set_width(1.4) %>% 234 | huxtable::set_escape_contents(FALSE) %>% 235 | huxtable::set_bold(1:3, 1:11, TRUE) %>% 236 | huxtable::set_valign(1:3, 1:11, "bottom") %>% 237 | huxtable::set_align(3, 1:11, "center") %>% 238 | huxtable::set_align(1, 1:11, "center") 239 | 240 | # Write into doc object and pull titles/footnotes from excel file 241 | doc <- rtf_doc(ht2, header_rows = 3) %>% titles_and_footnotes_from_df( 242 | from.file='./data/titles.xlsx', 243 | reader=example_custom_reader, 244 | table_number='14-6.02') %>% 245 | set_font_size(10) %>% 246 | set_ignore_cell_padding(TRUE) %>% 247 | set_column_header_buffer(top = 1) %>% 248 | set_footer_height(1) %>% 249 | set_header_height(1) 250 | 251 | 252 | # Write out the RTF 253 | write_rtf(doc, file='./outputs/14-6.02.rtf') 254 | 255 | -------------------------------------------------------------------------------- /programs/t-14-6.03.R: -------------------------------------------------------------------------------- 1 | # Table 14-6.03 2 | 3 | library(huxtable) 4 | library(dplyr) 5 | library(glue) 6 | library(tidyverse) 7 | library(haven) 8 | library(pharmaRTF) 9 | library(tibble) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | n_pct <- function(n, pct, n_width=3, pct_width=3) { 15 | n <- unlist(n) 16 | pct <- unique(pct) 17 | # n (%) formatted string. e.g. 50 ( 75%) 18 | unlist(lapply(n, function(x) { 19 | if(x == 0) " 0 " 20 | else { 21 | as.character( 22 | # Form the string using glue and format 23 | glue('{format(x, width=n_width)}({format(round((x/pct) * 100), width=pct_width)}%)') 24 | ) 25 | } 26 | })) 27 | } 28 | 29 | ## Chem 30 | adlbc <- read_xpt(glue("{adam_lib}/adlbcpv.xpt")) %>% 31 | filter(SAFFL == "Y", ANL01FL == "Y", AVISITN != 99) 32 | 33 | adlbc$TRTP <- ordered(adlbc$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 34 | adlbc$PARAM <- recode(adlbc$PARAM, 35 | "Albumin (g/L) change from previous visit, relative to normal range" = "ALBUMIN", 36 | "Alkaline Phosphatase (U/L) change from previous visit, relative to normal range" = "ALKALINE PHOSPHATASE", 37 | "Alanine Aminotransferase (U/L) change from previous visit, relative to normal range" = "ALANINE AMINOTRANSFERASE", 38 | "Aspartate Aminotransferase (U/L) change from previous visit, relative to normal range" = "ASPARTATE AMINOTRANSFERASE", 39 | "Bilirubin (umol/L) change from previous visit, relative to normal range" = "BILIRUBIN", 40 | "Blood Urea Nitrogen (mmol/L) change from previous visit, relative to normal range" = "UREA NITROGEN", 41 | "Calcium (mmol/L) change from previous visit, relative to normal range" = "CALCIUM", 42 | "Cholesterol (mmol/L) change from previous visit, relative to normal range" = "CHOLESTEROL", 43 | "Creatine Kinase (U/L) change from previous visit, relative to normal range" = "CREATINE KINASE", 44 | "Chloride (mmol/L) change from previous visit, relative to normal range" = "CHLORIDE", 45 | "Creatinine (umol/L) change from previous visit, relative to normal range" = "CREATININE", 46 | "Gamma Glutamyl Transferase (U/L) change from previous visit, relative to normal range" = "GAMMA GLUTAMYL TRANSFERASE", 47 | "Glucose (mmol/L) change from previous visit, relative to normal range" = "GLUCOSE", 48 | "Potassium (mmol/L) change from previous visit, relative to normal range" = "POTASSIUM", 49 | "Sodium (mmol/L) change from previous visit, relative to normal range" = "SODIUM", 50 | "Phosphate (mmol/L) change from previous visit, relative to normal range" = "PHOSPHATE", 51 | "Protein (g/L) change from previous visit, relative to normal range" = "PROTEIN", 52 | "Urate (umol/L) change from previous visit, relative to normal range" = "URATE" 53 | ) 54 | adlbc$PARAM <- ordered(adlbc$PARAM, c( 55 | "ALBUMIN", 56 | "ALKALINE PHOSPHATASE", 57 | "ALANINE AMINOTRANSFERASE", 58 | "ASPARTATE AMINOTRANSFERASE", 59 | "BILIRUBIN", 60 | "UREA NITROGEN", 61 | "CALCIUM", 62 | "CHOLESTEROL", 63 | "CREATINE KINASE", 64 | "CHLORIDE", 65 | "CREATININE", 66 | "GAMMA GLUTAMYL TRANSFERASE", 67 | "GLUCOSE", 68 | "POTASSIUM", 69 | "SODIUM", 70 | "PHOSPHATE", 71 | "PROTEIN", 72 | "URATE" 73 | )) 74 | adlbc$ANRIND <- ordered(adlbc$ANRIND, c("L", "N", "H")) 75 | 76 | adlbc2 <- adlbc %>% 77 | filter(!is.na(TRTP)) %>% 78 | group_by(PARAM, TRTP, ANRIND) %>% 79 | complete(nesting(PARAM, TRTP, ANRIND)) %>% 80 | summarise(N = n()) %>% 81 | group_by(PARAM, TRTP) %>% 82 | mutate(tot = sum(N)) 83 | 84 | adlbc_pvals <- list() 85 | 86 | for(i in seq(nrow(adlbc2)/9)) { 87 | adlbc_pvals[i] <- round(fisher.test( 88 | matrix(unlist(adlbc2[((i-1)*9+1):(i*9), "N"]), nrow = 3, ncol = 3, byrow = TRUE) 89 | )$p.value, 3) 90 | } 91 | 92 | adlbc3 <- adlbc2 %>% 93 | mutate(n_w_pct = n_pct(N, tot, n_width = 2)) %>% 94 | pivot_wider(id_cols = PARAM,names_from = c(TRTP, ANRIND), values_from = n_w_pct) %>% 95 | add_column("p-val\\line [1]" = num_fmt(unlist(adlbc_pvals), digits = 3, int_len = 1, size = 5)) 96 | 97 | ### Heme 98 | adlbh <- read_xpt(glue("{adam_lib}/adlbhpv.xpt")) %>% 99 | filter(SAFFL == "Y", ANL01FL == "Y", AVISITN != 99) 100 | 101 | adlbh$TRTP <- ordered(adlbh$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 102 | adlbh$PARAM <- recode(adlbh$PARAM, 103 | "Basophils (GI/L) change from previous visit, relative to normal range" = "BASOPHILS", 104 | "Eosinophils (GI/L) change from previous visit, relative to normal range" = "EOSINOPHILS", 105 | "Hematocrit change from previous visit, relative to normal range" = "HEMATOCRIT", 106 | "Hemoglobin (mmol/L) change from previous visit, relative to normal range" = "HEMOGLOBIN", 107 | "Lymphocytes (GI/L) change from previous visit, relative to normal range" = "LYMPHOCYTES", 108 | "Ery. Mean Corpuscular Hemoglobin (fmol(Fe)) change from previous visit, relative to normal range" = "ERY. MEAN CORPUSCULAR HEMOGLOBIN", 109 | "Ery. Mean Corpuscular HGB Concentration (mmol/L) change from previous visit, relative to normal rang" = "ERY. MEAN CORPUSCULAR HB CONCENTRATION", 110 | "Ery. Mean Corpuscular Volume (fL) change from previous visit, relative to normal range" = "ERY. MEAN CORPUSCULAR VOLUME", 111 | "Monocytes (GI/L) change from previous visit, relative to normal range" = "MONOCYTES", 112 | "Platelet (GI/L) change from previous visit, relative to normal range" = "PLATELET", 113 | "Erythrocytes (TI/L) change from previous visit, relative to normal range" = "ERYTHROCYTES", 114 | "Leukocytes (GI/L) change from previous visit, relative to normal range" = "LEUKOCYTES" 115 | ) 116 | adlbh$PARAM <- ordered(adlbh$PARAM, c( 117 | "BASOPHILS", 118 | "EOSINOPHILS", 119 | "HEMATOCRIT", 120 | "HEMOGLOBIN", 121 | "LYMPHOCYTES", 122 | "ERY. MEAN CORPUSCULAR HEMOGLOBIN", 123 | "ERY. MEAN CORPUSCULAR HB CONCENTRATION", 124 | "ERY. MEAN CORPUSCULAR VOLUME", 125 | "MONOCYTES", 126 | "PLATELET", 127 | "ERYTHROCYTES", 128 | "LEUKOCYTES" 129 | )) 130 | adlbh$ANRIND <- ordered(adlbh$ANRIND, c("L", "N", "H")) 131 | 132 | 133 | adlbh2 <- adlbh %>% 134 | filter(!is.na(PARAM), !is.na(TRTP)) %>% 135 | group_by(PARAM, TRTP, ANRIND) %>% 136 | complete(nesting(PARAM, TRTP, ANRIND)) %>% 137 | summarise(N = n()) %>% 138 | group_by(PARAM, TRTP) %>% 139 | mutate(tot = sum(N)) 140 | 141 | adlbh_pvals <- list() 142 | 143 | for(i in seq(nrow(adlbh2)/9)) { 144 | adlbh_pvals[i] <- round(fisher.test( 145 | matrix(unlist(adlbh2[((i-1)*9+1):(i*9), "N"]), nrow = 3, ncol = 3, byrow = TRUE) 146 | )$p.value, 3) 147 | } 148 | 149 | adlbh3 <- adlbh2 %>% 150 | mutate(n_w_pct = n_pct(N, tot, n_width = 2)) %>% 151 | pivot_wider(id_cols = PARAM,names_from = c(TRTP, ANRIND), values_from = n_w_pct) %>% 152 | add_column("p-val\\line [1]" = num_fmt(unlist(adlbh_pvals), digits = 3, int_len = 1, size = 5)) 153 | 154 | final <- adlbc3 %>% 155 | ungroup() %>% 156 | add_row("PARAM" = "----------", .before = 1) %>% 157 | add_row("PARAM" = "CHEMISTRY", .before = 1) %>% 158 | add_row("PARAM" = "", .before = 1) %>% 159 | add_row("PARAM" = "") %>% 160 | add_row("PARAM" = "") %>% 161 | add_row("PARAM" = "") %>% 162 | add_row("PARAM" = "") %>% 163 | add_row("PARAM" = "") %>% 164 | add_row("PARAM" = "HEMATOLOGY") %>% 165 | add_row("PARAM" = "----------") %>% 166 | rbind(ungroup(adlbh3)) 167 | 168 | 169 | names(final) <- c( 170 | "", 171 | "Low", 172 | "Normal", 173 | "High", 174 | "Low", 175 | "Normal", 176 | "High", 177 | "Low", 178 | "Normal", 179 | "High", 180 | "p-val\\line[1]" 181 | ) 182 | 183 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 184 | headers <- adsl %>% 185 | filter(ARM != "Screen Failure") %>% 186 | group_by(ARM) %>% 187 | summarise(N = n()) %>% 188 | mutate(label = paste0(recode(ARM, 189 | "Placebo" = "Placebo", 190 | "Xanomeline Low Dose" = "Xan. Low", 191 | "Xanomeline High Dose" = "Xan. High"), " (N=", N, ")")) 192 | pad_row <- function(df, r) { 193 | #df - dataframe to insert pad 194 | #r - row number to pad 195 | for(i in seq(along = r)) { 196 | if(r[i] + i - 1 < nrow(df)){ 197 | df[seq(r[i] + i, nrow(df) + 1),] <- df[seq(r[i] + (i - 1), nrow(df)),] 198 | df[r[i] + (i - 1),] <- NA 199 | } else { 200 | df[r[i] + (i - 1),] <- NA 201 | } 202 | } 203 | df 204 | } 205 | 206 | ht <- final %>% 207 | as_huxtable(add_colnames = TRUE) 208 | 209 | ht <- as_hux(pad_row(as.data.frame(ht), c(1,1)), add_colnames = FALSE) 210 | ht[1, 2] <- headers[1, "label"] 211 | ht[1, 5] <- headers[3, "label"] 212 | ht[1, 8] <- headers[2, "label"] 213 | 214 | ht2 <- ht %>% 215 | huxtable::merge_cells(1, 2:4) %>% 216 | huxtable::merge_cells(1, 5:7) %>% 217 | huxtable::merge_cells(1, 8:10) %>% 218 | huxtable::set_bottom_border(2, 2:4, 1) %>% 219 | huxtable::set_bottom_border(2, 5:7, 1) %>% 220 | huxtable::set_bottom_border(2, 8:10, 1) %>% 221 | huxtable::set_bottom_border(3, 1:11, 1) %>% 222 | huxtable::set_col_width(1:11, c(0.18, rep(0.082, 10))) %>% 223 | huxtable::set_width(1.4) %>% 224 | huxtable::set_escape_contents(FALSE) %>% 225 | huxtable::set_bold(1:3, 1:11, TRUE) %>% 226 | huxtable::set_valign(1:3, 1:11, "bottom") %>% 227 | huxtable::set_align(3, 1:11, "center") %>% 228 | huxtable::set_align(1, 1:11, "center") 229 | 230 | # Write into doc object and pull titles/footnotes from excel file 231 | doc <- rtf_doc(ht2, header_rows = 3) %>% titles_and_footnotes_from_df( 232 | from.file='./data/titles.xlsx', 233 | reader=example_custom_reader, 234 | table_number='14-6.03') %>% 235 | set_font_size(10) %>% 236 | set_ignore_cell_padding(TRUE) %>% 237 | set_column_header_buffer(top = 1) %>% 238 | set_footer_height(1.25) 239 | 240 | 241 | # Write out the RTF 242 | write_rtf(doc, file='./outputs/14-6.03.rtf') 243 | 244 | -------------------------------------------------------------------------------- /programs/t-14-6.04.R: -------------------------------------------------------------------------------- 1 | # T-14-6.04 2 | 3 | library(huxtable) 4 | library(dplyr) 5 | library(glue) 6 | library(tidyverse) 7 | library(haven) 8 | library(pharmaRTF) 9 | library(tibble) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | pad_row <- function(df, r) { 15 | #df - dataframe to insert pad 16 | #r - row number to pad 17 | for(i in seq(along = r)) { 18 | if(r[i] + i - 1 < nrow(df)){ 19 | df[seq(r[i] + i, nrow(df) + 1),] <- df[seq(r[i] + (i - 1), nrow(df)),] 20 | df[r[i] + (i - 1),] <- NA 21 | } else { 22 | df[r[i] + (i - 1),] <- NA 23 | } 24 | } 25 | df 26 | } 27 | 28 | n_pct <- function(n, pct, n_width=3, pct_width=3) { 29 | n <- unlist(n) 30 | pct <- unique(pct) 31 | # n (%) formatted string. e.g. 50 ( 75%) 32 | unlist(lapply(n, function(x) { 33 | if(x == 0) " 0 " 34 | else { 35 | as.character( 36 | # Form the string using glue and format 37 | glue('{format(x, width=n_width)}({format(round((x/pct) * 100), width=pct_width)}%)') 38 | ) 39 | } 40 | })) 41 | } 42 | 43 | ## Chem 44 | adlbc <- read_xpt(glue("{adam_lib}/adlbc.xpt")) %>% 45 | filter(SAFFL == "Y", AVISITN != 99) 46 | adlbh <- read_xpt(glue("{adam_lib}/adlbh.xpt")) %>% 47 | filter(SAFFL == "Y", AVISITN != 99) 48 | comb <- rbind(adlbc, adlbh) 49 | 50 | #sort tests 51 | comb$PARAM<- recode(comb$PARAM, 52 | "Alanine Aminotransferase (U/L)" = "ALANINE AMINOTRANSFERASE", 53 | "Albumin (g/L)" = "ALBUMIN", 54 | "Alkaline Phosphatase (U/L)" = "ALKALINE PHOSPHATASE", 55 | "Aspartate Aminotransferase (U/L)" = "ASPARTATE AMINOTRANSFERASE", 56 | "Bilirubin (umol/L)" = "BILIRUBIN", 57 | "Calcium (mmol/L)" = "CALCIUM", 58 | "Chloride (mmol/L)" = "CHLORIDE", 59 | "Cholesterol (mmol/L)" = "CHOLESTEROL", 60 | "Creatine Kinase (U/L)" = "CREATINE KINASE", 61 | "Creatinine (umol/L)" = "CREATININE", 62 | "Gamma Glutamyl Transferase (U/L)" = "GAMMA GLUTAMYL TRANSFERASE", 63 | "Glucose (mmol/L)" = "GLUCOSE", 64 | "Phosphate (mmol/L)" = "PHOSPHATE", 65 | "Potassium (mmol/L)" = "POTASSIUM", 66 | "Protein (g/L)" = "PROTEIN", 67 | "Sodium (mmol/L)" = "SODIUM", 68 | "Urate (umol/L)" = "URATE", 69 | "Blood Urea Nitrogen (mmol/L)" = "UREA NITROGEN", 70 | "Basophils (GI/L)" = "BASOPHILS", 71 | "Eosinophils (GI/L)" = "EOSINOPHILS", 72 | "Ery. Mean Corpuscular HGB Concentration (mmol/L)" = "ERY. MEAN CORPUSCULAR HB CONCENTRATION", 73 | "Ery. Mean Corpuscular Hemoglobin (fmol(Fe))" = "ERY. MEAN CORPUSCULAR HEMOGLOBIN", 74 | "Ery. Mean Corpuscular Volume (fL)" = "ERY. MEAN CORPUSCULAR VOLUME", 75 | "Erythrocytes (TI/L)" = "ERYTHROCYTES", 76 | "Hematocrit" = "HEMATOCRIT", 77 | "Hemoglobin (mmol/L)" = "HEMOGLOBIN", 78 | "Leukocytes (GI/L)" = "LEUKOCYTES", 79 | "Lymphocytes (GI/L)" = "LYMPHOCYTES", 80 | "Monocytes (GI/L)" = "MONOCYTES", 81 | "Platelet (GI/L)" = "PLATELET") 82 | #sort tests 83 | comb$PARAM <-ordered(comb$PARAM, c( 84 | "ALANINE AMINOTRANSFERASE", 85 | "ALBUMIN", 86 | "ALKALINE PHOSPHATASE", 87 | "ASPARTATE AMINOTRANSFERASE", 88 | "BILIRUBIN", 89 | "CALCIUM", 90 | "CHLORIDE", 91 | "CHOLESTEROL", 92 | "CREATINE KINASE", 93 | "CREATININE", 94 | "GAMMA GLUTAMYL TRANSFERASE", 95 | "GLUCOSE", 96 | "PHOSPHATE", 97 | "POTASSIUM", 98 | "PROTEIN", 99 | "SODIUM", 100 | "URATE", 101 | "UREA NITROGEN", 102 | "BASOPHILS", 103 | "EOSINOPHILS", 104 | "ERY. MEAN CORPUSCULAR HB CONCENTRATION", 105 | "ERY. MEAN CORPUSCULAR HEMOGLOBIN", 106 | "ERY. MEAN CORPUSCULAR VOLUME", 107 | "ERYTHROCYTES", 108 | "HEMATOCRIT", 109 | "HEMOGLOBIN", 110 | "LEUKOCYTES", 111 | "LYMPHOCYTES", 112 | "MONOCYTES", 113 | "PLATELET")) 114 | comb$TRTP <- ordered(comb$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 115 | comb$ANRIND <- ordered(comb$ANRIND, c("N", "H")) 116 | comb$BNRIND <- ordered(comb$BNRIND, c("N", "H")) 117 | comb$VISIT <- ordered(comb$VISIT, c( 118 | "WEEK 2", 119 | "WEEK 4", 120 | "WEEK 6", 121 | "WEEK 8", 122 | "WEEK 12", 123 | "WEEK 16", 124 | "WEEK 20", 125 | "WEEK 24", 126 | "WEEK 26" 127 | )) 128 | 129 | total_ABLFL1 <- comb%>% 130 | filter(!is.na(VISIT), !is.na(TRTP), !is.na(BNRIND), !is.na(ANRIND), !is.na(PARAM)) %>% 131 | group_by(PARAM, VISIT, TRTP, BNRIND) %>% 132 | complete(nesting(TRTP, ABLFL)) %>% 133 | summarise(N = n()) 134 | total_ABLFL <- total_ABLFL1 %>% 135 | mutate(ANRIND = ordered("T", c("T", "N", "H"))) %>% 136 | pivot_wider(id_cols = c(PARAM, VISIT, ANRIND), names_from = c(TRTP, BNRIND), values_from = N) %>% 137 | ungroup() 138 | 139 | comb2 <- comb %>% 140 | filter(!is.na(VISIT), !is.na(TRTP), !is.na(BNRIND), !is.na(ANRIND), !is.na(PARAM)) %>% 141 | group_by(PARAM, VISIT, TRTP, BNRIND, ANRIND) %>% 142 | complete(nesting(BNRIND, ANRIND)) %>% 143 | summarise(N = n()) %>% 144 | mutate(n2 = n_pct(N, total_ABLFL1[total_ABLFL1$PARAM == PARAM & 145 | total_ABLFL1$VISIT == VISIT & 146 | total_ABLFL1$TRTP == TRTP & 147 | total_ABLFL1$BNRIND == BNRIND, "N"], n_width = 2)) %>% 148 | ungroup() %>% 149 | pivot_wider(id_cols = c(PARAM, VISIT, ANRIND), names_from = c(TRTP, BNRIND), values_from = n2) 150 | 151 | comb2$ANRIND <- ordered(comb2$ANRIND, c("T", "N", "H")) 152 | 153 | total_ABLFL$Placebo_N <- num_fmt(total_ABLFL$Placebo_N, size = 2, int_len = 2) 154 | total_ABLFL$Placebo_H <- num_fmt(total_ABLFL$Placebo_H, size = 2, int_len = 2) 155 | total_ABLFL$`Xanomeline Low Dose_N` <- num_fmt(total_ABLFL$`Xanomeline Low Dose_N`, size = 2, int_len = 2) 156 | total_ABLFL$`Xanomeline Low Dose_H` <- num_fmt(total_ABLFL$`Xanomeline Low Dose_H`, size = 2, int_len = 2) 157 | total_ABLFL$`Xanomeline High Dose_N` <- num_fmt(total_ABLFL$`Xanomeline High Dose_N`, size = 2, int_len = 2) 158 | total_ABLFL$`Xanomeline High Dose_H` <- num_fmt(total_ABLFL$`Xanomeline High Dose_H`, size = 2, int_len = 2) 159 | 160 | comb3 <- comb2 %>% 161 | rbind(total_ABLFL) %>% 162 | arrange(PARAM, VISIT, ANRIND) 163 | 164 | comb3$VISIT <- as.character(str_extract(comb3$VISIT, "[0-9]+")) 165 | comb3$ANRIND <- as.character(recode(comb3$ANRIND, 166 | "T" = "n", 167 | "N" = "Normal", 168 | "H" = "High")) 169 | names(comb3) <- c( 170 | "rowlbl", 171 | "Week", 172 | "Shift to", 173 | "Normal at Baseline", 174 | "High at Baseline", 175 | "Normal at Baseline", 176 | "High at Baseline", 177 | "Normal at Baseline", 178 | "High at Baseline" 179 | ) 180 | 181 | comb3 <- comb3[!apply(comb3, 1, function(x) { 182 | all(x[4:9] == " 0 ") & all(x[3] == "High") 183 | }), ] 184 | 185 | comb4 <- pad_row(comb3, which(comb3$`Shift to` == "n")) %>% 186 | add_row('Week' = NA, .before = 1) %>% 187 | add_row("Week" = NA, .before = 1) 188 | comb4 <- comb4 %>% 189 | add_row("Week" = NA, .before = 541) %>% 190 | add_row("Week" = NA, .before = 541) 191 | 192 | comb4[,1] <- as.character(comb4$rowlbl) 193 | 194 | comb4[!(comb4$`Shift to` %in% "n") , 2] <- NA 195 | comb4[!(comb4$Week %in% "2"), 1] <- NA 196 | comb4[2,1] <- "CHEMISTRY" 197 | comb4[3,1] <- "----------" 198 | comb4[542,1] <- "HEMATOLOGY" 199 | comb4[543,1] <- "----------" 200 | 201 | 202 | names(comb4) <- c( 203 | "", 204 | "Week", 205 | "Shift to", 206 | "Normal at Baseline", 207 | "High at Baseline", 208 | "Normal at Baseline", 209 | "High at Baseline", 210 | "Normal at Baseline", 211 | "High at Baseline" 212 | ) 213 | 214 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 215 | headers <- adsl %>% 216 | filter(ARM != "Screen Failure") %>% 217 | group_by(ARM) %>% 218 | summarise(N = n()) %>% 219 | mutate(label = paste0(recode(ARM, 220 | "Placebo" = "Placebo", 221 | "Xanomeline Low Dose" = "Xan. Low", 222 | "Xanomeline High Dose" = "Xan. High"), " (N=", N, ")")) 223 | 224 | 225 | 226 | ht <- comb4 %>% 227 | as_huxtable(add_colnames = TRUE) 228 | 229 | ht <- as_hux(pad_row(as.data.frame(ht), c(1,1)), add_colnames = FALSE) 230 | ht[1, 4] <- headers[1, "label"] 231 | ht[1, 6] <- headers[3, "label"] 232 | ht[1, 8] <- headers[2, "label"] 233 | 234 | ht2 <- ht %>% 235 | huxtable::merge_cells(1, 4:5) %>% 236 | huxtable::merge_cells(1, 6:7) %>% 237 | huxtable::merge_cells(1, 8:9) %>% 238 | huxtable::set_bottom_border(2, 4:5, 1) %>% 239 | huxtable::set_bottom_border(2, 6:7, 1) %>% 240 | huxtable::set_bottom_border(2, 8:9, 1) %>% 241 | huxtable::set_bottom_border(3, 1:9, 1) %>% 242 | huxtable::set_width(1.4) %>% 243 | huxtable::set_escape_contents(FALSE) %>% 244 | huxtable::set_bold(1:3, 1:9, TRUE) %>% 245 | huxtable::set_valign(1:3, 1:9, "bottom") %>% 246 | huxtable::set_align(3, 1:9, "center") %>% 247 | huxtable::set_align(1, 1:9, "center") %>% 248 | huxtable::set_col_width(1:9, c(0.29, 0.06, 0.07, rep(0.1, 6))) 249 | 250 | # Write into doc object and pull titles/footnotes from excel file 251 | doc <- rtf_doc(ht2, header_rows = 3) %>% titles_and_footnotes_from_df( 252 | from.file='./data/titles.xlsx', 253 | reader=example_custom_reader, 254 | table_number='14-6.04') %>% 255 | set_font_size(10) %>% 256 | set_ignore_cell_padding(TRUE) %>% 257 | set_column_header_buffer(top = 1) %>% 258 | set_header_height(0.75) %>% 259 | set_footer_height(1) 260 | 261 | 262 | # Write out the RTF 263 | write_rtf(doc, file='./outputs/14-6.04.rtf') 264 | 265 | 266 | -------------------------------------------------------------------------------- /programs/t-14-6.05.R: -------------------------------------------------------------------------------- 1 | ## 14-6.05 2 | 3 | library(huxtable) 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(tibble) 8 | library(pharmaRTF) 9 | 10 | source('./programs/config.R') 11 | source('./programs/funcs.R') 12 | 13 | pad_row <- function(df, r) { 14 | #df - dataframe to insert pad 15 | #r - row number to pad 16 | for(i in seq(along = r)) { 17 | if(r[i] + i - 1 < nrow(df)){ 18 | df[seq(r[i] + i, nrow(df) + 1),] <- df[seq(r[i] + (i - 1), nrow(df)),] 19 | df[r[i] + (i - 1),] <- NA 20 | } else { 21 | df[r[i] + (i - 1),] <- NA 22 | } 23 | } 24 | df 25 | } 26 | 27 | n_pct <- function(n, pct, n_width=3, pct_width=3) { 28 | n <- unlist(n) 29 | pct <- unique(pct) 30 | # n (%) formatted string. e.g. 50 ( 75%) 31 | unlist(lapply(n, function(x) { 32 | if(x == 0) " 0 " 33 | else { 34 | as.character( 35 | # Form the string using glue and format 36 | glue('{format(x, width=n_width)}({format(round((x/pct) * 100), width=pct_width)}%)') 37 | ) 38 | } 39 | })) 40 | } 41 | 42 | adlbc <- read_xpt(glue("{adam_lib}/adlbc.xpt")) %>% 43 | filter(SAFFL == "Y", ANL01FL == "Y") 44 | adlbh <- read_xpt(glue("{adam_lib}/adlbh.xpt")) %>% 45 | filter(SAFFL == "Y", ANL01FL == "Y") 46 | comb <- rbind(adlbc, adlbh) 47 | 48 | 49 | comb$PARAM<- recode(comb$PARAM, 50 | "Alanine Aminotransferase (U/L)" = "ALANINE AMINOTRANSFERASE", 51 | "Albumin (g/L)" = "ALBUMIN", 52 | "Alkaline Phosphatase (U/L)" = "ALKALINE PHOSPHATASE", 53 | "Aspartate Aminotransferase (U/L)" = "ASPARTATE AMINOTRANSFERASE", 54 | "Bilirubin (umol/L)" = "BILIRUBIN", 55 | "Calcium (mmol/L)" = "CALCIUM", 56 | "Chloride (mmol/L)" = "CHLORIDE", 57 | "Cholesterol (mmol/L)" = "CHOLESTEROL", 58 | "Creatine Kinase (U/L)" = "CREATINE KINASE", 59 | "Creatinine (umol/L)" = "CREATININE", 60 | "Gamma Glutamyl Transferase (U/L)" = "GAMMA GLUTAMYL TRANSFERASE", 61 | "Glucose (mmol/L)" = "GLUCOSE", 62 | "Phosphate (mmol/L)" = "PHOSPHATE", 63 | "Potassium (mmol/L)" = "POTASSIUM", 64 | "Protein (g/L)" = "PROTEIN", 65 | "Sodium (mmol/L)" = "SODIUM", 66 | "Urate (umol/L)" = "URATE", 67 | "Blood Urea Nitrogen (mmol/L)" = "UREA NITROGEN", 68 | "Basophils (GI/L)" = "BASOPHILS", 69 | "Eosinophils (GI/L)" = "EOSINOPHILS", 70 | "Ery. Mean Corpuscular HGB Concentration (mmol/L)" = "ERY. MEAN CORPUSCULAR HB CONCENTRATION", 71 | "Ery. Mean Corpuscular Hemoglobin (fmol(Fe))" = "ERY. MEAN CORPUSCULAR HEMOGLOBIN", 72 | "Ery. Mean Corpuscular Volume (fL)" = "ERY. MEAN CORPUSCULAR VOLUME", 73 | "Erythrocytes (TI/L)" = "ERYTHROCYTES", 74 | "Hematocrit" = "HEMATOCRIT", 75 | "Hemoglobin (mmol/L)" = "HEMOGLOBIN", 76 | "Leukocytes (GI/L)" = "LEUKOCYTES", 77 | "Lymphocytes (GI/L)" = "LYMPHOCYTES", 78 | "Monocytes (GI/L)" = "MONOCYTES", 79 | "Platelet (GI/L)" = "PLATELET") 80 | #sort tests 81 | comb$PARAM <-ordered(comb$PARAM, c( 82 | "ALANINE AMINOTRANSFERASE", 83 | "ALBUMIN", 84 | "ALKALINE PHOSPHATASE", 85 | "ASPARTATE AMINOTRANSFERASE", 86 | "BILIRUBIN", 87 | "CALCIUM", 88 | "CHLORIDE", 89 | "CHOLESTEROL", 90 | "CREATINE KINASE", 91 | "CREATININE", 92 | "GAMMA GLUTAMYL TRANSFERASE", 93 | "GLUCOSE", 94 | "PHOSPHATE", 95 | "POTASSIUM", 96 | "PROTEIN", 97 | "SODIUM", 98 | "URATE", 99 | "UREA NITROGEN", 100 | "BASOPHILS", 101 | "EOSINOPHILS", 102 | "ERY. MEAN CORPUSCULAR HB CONCENTRATION", 103 | "ERY. MEAN CORPUSCULAR HEMOGLOBIN", 104 | "ERY. MEAN CORPUSCULAR VOLUME", 105 | "ERYTHROCYTES", 106 | "HEMATOCRIT", 107 | "HEMOGLOBIN", 108 | "LEUKOCYTES", 109 | "LYMPHOCYTES", 110 | "MONOCYTES", 111 | "PLATELET")) 112 | comb$TRTP <- ordered(comb$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 113 | comb$BNRIND <- ordered(comb$BNRIND, c("N", "H")) 114 | comb$ANRIND <- ordered(comb$ANRIND, c("N", "H")) 115 | 116 | comb <- comb %>% 117 | filter(!is.na(comb$PARAM), !is.na(comb$TRTP), !is.na(comb$BNRIND), !is.na(comb$ANRIND), AVISITN != 99) 118 | 119 | total_bltrfl1 <- comb%>% 120 | filter(!is.na(TRTP), !is.na(BNRIND), !is.na(ANRIND), !is.na(PARAM)) %>% 121 | group_by(PARAM, TRTP, BNRIND) %>% 122 | complete(nesting(TRTP, BNRIND)) %>% 123 | summarise(N = n()) 124 | total_bltrfl <- total_bltrfl1 %>% 125 | mutate(ANRIND = ordered("T", c("T", "N", "H"))) %>% 126 | pivot_wider(id_cols = c(PARAM, ANRIND), names_from = c(TRTP, BNRIND), values_from = N) %>% 127 | ungroup() 128 | 129 | comb2 <- comb %>% 130 | group_by(PARAM, TRTP, BNRIND, ANRIND) %>% 131 | complete(nesting(BNRIND, ANRIND)) %>% 132 | summarise(N = n()) %>% 133 | ungroup() 134 | 135 | 136 | pvals <- c() 137 | for(i in levels(comb$PARAM)) { 138 | mat <- comb[comb$PARAM == i, c("ANRIND", "TRTP", "BNRIND")] 139 | 140 | if(all(mat[, "ANRIND"] == "N")) pvals[i] <- "" 141 | else { 142 | pvals[i] <- tryCatch(num_fmt(cmh_p(mat, ANRIND ~ TRTP | BNRIND, alternate = "rmeans"), digits = 3, int_len = 1), 143 | error = function(c) "" 144 | ) 145 | } 146 | } 147 | 148 | temp1 <- mat %>% 149 | group_by(TRTP) %>% 150 | summarise(n = n()) 151 | 152 | comb3 <- comb2 %>% 153 | group_by(PARAM, TRTP, BNRIND) %>% 154 | mutate(n2 = n_pct(N, total_bltrfl1[total_bltrfl1$PARAM == PARAM & 155 | total_bltrfl1$TRTP == TRTP & 156 | total_bltrfl1$BNRIND == BNRIND, "N"], n_width = 2)) %>% 157 | ungroup() %>% 158 | pivot_wider(id_cols = c(PARAM, ANRIND), names_from = c(TRTP, BNRIND), values_from = n2) 159 | 160 | comb4 <- comb3[!apply(comb3, 1, function(x) { 161 | all(x[3:8] == " 0 ") & all(x[2] == "H") 162 | }), ] 163 | 164 | 165 | comb4$ANRIND <- ordered(comb4$ANRIND, c("T", "N", "H")) 166 | 167 | total_bltrfl$Placebo_N <- num_fmt(total_bltrfl$Placebo_N, size = 2, int_len = 2) 168 | total_bltrfl$Placebo_H <- num_fmt(total_bltrfl$Placebo_H, size = 2, int_len = 2) 169 | total_bltrfl$`Xanomeline Low Dose_N` <- num_fmt(total_bltrfl$`Xanomeline Low Dose_N`, size = 2, int_len = 2) 170 | total_bltrfl$`Xanomeline Low Dose_H` <- num_fmt(total_bltrfl$`Xanomeline Low Dose_H`, size = 2, int_len = 2) 171 | total_bltrfl$`Xanomeline High Dose_N` <- num_fmt(total_bltrfl$`Xanomeline High Dose_N`, size = 2, int_len = 2) 172 | total_bltrfl$`Xanomeline High Dose_H` <- num_fmt(total_bltrfl$`Xanomeline High Dose_H`, size = 2, int_len = 2) 173 | 174 | 175 | 176 | comb5 <- comb4 %>% 177 | rbind(total_bltrfl) %>% 178 | arrange(PARAM, ANRIND) 179 | 180 | comb5$ANRIND <- as.character(recode(comb5$ANRIND, 181 | "T" = "n", 182 | "N" = "Normal", 183 | "H" = "High")) 184 | 185 | comb5[unlist(comb5[,2] == "n")[,1], 9] <- pvals 186 | comb5 <- pad_row(comb5, which(comb5[,2] == "n")) %>% 187 | ungroup() %>% 188 | add_row("PARAM" = NA, .before = 1) %>% 189 | add_row("PARAM" = NA, .before = 1) 190 | comb5 <- comb5 %>% 191 | add_row("PARAM" = NA, .before = 65) %>% 192 | add_row("PARAM" = NA, .before = 65) 193 | 194 | comb5[!(unlist(comb5[,2]) %in% "n") , 1] <- NA 195 | 196 | comb5 <- comb5[!apply(comb5, 1, function(x) { 197 | all(x[4:9] == " 0 ") & all(x[3] == "High") 198 | }), ] 199 | 200 | comb5[,1] <- as.character(comb5$PARAM) 201 | comb5[2,1] <- "CHEMISTRY" 202 | comb5[3,1] <- "----------" 203 | comb5[66,1] <- "HEMATOLOGY" 204 | comb5[67,1] <- "----------" 205 | 206 | names(comb5) <- c( 207 | "", 208 | "Shift\\line[1]", 209 | "Normal at Baseline", 210 | "High at Baseline", 211 | "Normal at Baseline", 212 | "High at Baseline", 213 | "Normal at Baseline", 214 | "High at Baseline", 215 | "p-\\line value\\line[2]" 216 | ) 217 | 218 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 219 | headers <- adsl %>% 220 | filter(ARM != "Screen Failure") %>% 221 | group_by(ARM) %>% 222 | summarise(N = n()) %>% 223 | mutate(label = paste0(recode(ARM, 224 | "Placebo" = "Placebo", 225 | "Xanomeline Low Dose" = "Xan. Low", 226 | "Xanomeline High Dose" = "Xan. High"), " (N=", N, ")")) 227 | 228 | ht <- comb5 %>% 229 | huxtable::as_hux(add_colnames=TRUE) 230 | 231 | ht <- as_hux(pad_row(as.data.frame(ht), c(1,1)), add_colnames = FALSE) 232 | ht[1, 3] <- headers[1, "label"] 233 | ht[1, 5] <- headers[3, "label"] 234 | ht[1, 7] <- headers[2, "label"] 235 | 236 | ht2 <- ht %>% 237 | huxtable::merge_cells(1, 3:4) %>% 238 | huxtable::merge_cells(1, 5:6) %>% 239 | huxtable::merge_cells(1, 7:8) %>% 240 | huxtable::set_bottom_border(2, 3:4, 1) %>% 241 | huxtable::set_bottom_border(2, 5:6, 1) %>% 242 | huxtable::set_bottom_border(2, 7:8, 1) %>% 243 | huxtable::set_bottom_border(3, 1:9, 1) %>% 244 | huxtable::set_width(1.5) %>% 245 | huxtable::set_escape_contents(FALSE) %>% 246 | huxtable::set_bold(1:3, 1:9, TRUE) %>% 247 | huxtable::set_valign(1:3, 1:9, "bottom") %>% 248 | huxtable::set_align(3, 1:9, "center") %>% 249 | huxtable::set_align(1, 1:9, "center") %>% 250 | huxtable::set_align(4:102, 9, "right") %>% 251 | huxtable::set_col_width(1:9, c(0.31, rep(0.09, 7), 0.06)) 252 | 253 | 254 | # Write into doc object and pull titles/footnotes from excel file 255 | doc <- rtf_doc(ht2, header_rows = 3) %>% titles_and_footnotes_from_df( 256 | from.file='./data/titles.xlsx', 257 | reader=example_custom_reader, 258 | table_number='14-6.05') %>% 259 | set_font_size(10) %>% 260 | set_ignore_cell_padding(TRUE) %>% 261 | set_column_header_buffer(top = 1) %>% 262 | set_header_height(1) %>% 263 | set_footer_height(1.3) 264 | 265 | # Write out the RTF 266 | write_rtf(doc, file='./outputs/14-6.05.rtf') 267 | 268 | -------------------------------------------------------------------------------- /programs/t-14-6.06.R: -------------------------------------------------------------------------------- 1 | ## Table 14-6.06 2 | 3 | library(huxtable) 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(pharmaRTF) 8 | 9 | source('./programs/config.R') 10 | source('./programs/funcs.R') 11 | 12 | pad_row <- function(df, r) { 13 | #df - dataframe to insert pad 14 | #r - row number to pad 15 | for(i in seq(along = r)) { 16 | if(r[i] + i - 1 < nrow(df)){ 17 | df[seq(r[i] + i, nrow(df) + 1),] <- df[seq(r[i] + (i - 1), nrow(df)),] 18 | df[r[i] + (i - 1),] <- NA 19 | } else { 20 | df[r[i] + (i - 1),] <- NA 21 | } 22 | } 23 | df 24 | } 25 | 26 | n_pct <- function(n, pct, n_width=3, pct_width=3) { 27 | n <- unlist(n) 28 | pct <- unique(pct) 29 | # n (%) formatted string. e.g. 50 ( 75%) 30 | unlist(lapply(n, function(x) { 31 | if(x == 0) " 0 " 32 | else { 33 | as.character( 34 | # Form the string using glue and format 35 | glue('{format(x, width=n_width)}({format(round((x/pct) * 100), width=pct_width)}%)') 36 | ) 37 | } 38 | })) 39 | } 40 | 41 | # Old data used because new data is missing columns 42 | adlbhy <- read_xpt(glue("{adam_lib}/adlbhy.xpt")) %>% 43 | filter(SAFFL == "Y", PARAMCD %in% c("TRANSHY", "HYLAW"), !is.na(BASE), AVISITN > 0) 44 | 45 | adlbhy2 <- adlbhy %>% 46 | group_by(USUBJID) %>% 47 | filter(AVAL == max(AVAL)) %>% 48 | filter(AVISITN == max(AVISITN)) %>% 49 | ungroup() 50 | 51 | adlbhy2$BASE <- ordered(adlbhy2$BASE, c(0, 1)) 52 | adlbhy2$AVAL <- ordered(adlbhy2$AVAL, c(0, 1)) 53 | adlbhy2$TRTP <- ordered(adlbhy2$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 54 | 55 | total_t <- adlbhy2 %>% 56 | filter(!is.na(TRTP), !is.na(BASE), PARAMCD == "TRANSHY") %>% 57 | group_by(TRTP, BASE) %>% 58 | complete(nesting(TRTP, BASE)) %>% 59 | summarise(N = n(), 60 | Nc = num_fmt(n(), size = 2, int_len = 2)) 61 | total_tl <- total_t %>% 62 | mutate("Shift\\line[1]" = ordered("T", c("T", "N", "H"))) %>% 63 | pivot_wider(id_cols = c("Shift\\line[1]"), names_from = c(TRTP, BASE), values_from = Nc) 64 | 65 | adlbhy_t1 <- adlbhy2 %>% 66 | filter(PARAMCD == "TRANSHY") %>% 67 | group_by(TRTP, BASE, AVAL) %>% 68 | complete(nesting(BASE, AVAL)) %>% 69 | summarise(N = n()) 70 | adlbhy_t <- adlbhy_t1 %>% 71 | mutate(N2 = n_pct(N, total_t[total_t$TRTP == TRTP & 72 | total_t$BASE == BASE, "N"], n_width = 2)) %>% 73 | pivot_wider(id_cols = c("AVAL"), names_from = c("TRTP", "BASE"), values_from = c("N2")) 74 | 75 | names(adlbhy_t)[1] <- "Shift\\line[1]" 76 | 77 | total_t3 <- total_tl %>% 78 | rbind(adlbhy_t) 79 | 80 | total_t3[, " "] <- "Transaminase 1.5 x ULN" 81 | 82 | total_t3[, "p-\\line value\\line[2]"] <- c( 83 | num_fmt(mantelhaen.test(array(unlist(adlbhy_t1[,"N"]), dim = c(2,3,2)))$p.value, size = 6, int_len = 1, digits = 3) 84 | , "", "") 85 | 86 | adlbhy3 <- adlbhy2 %>% 87 | filter(PARAMCD %in% c("HYLAW")) 88 | 89 | adlbhy3$BASE <- ordered(adlbhy3$BASE, c(0, 1)) 90 | adlbhy3$AVAL <- ordered(adlbhy3$AVAL, c(0, 1)) 91 | adlbhy3$TRTP <- ordered(adlbhy3$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 92 | 93 | total_b <- adlbhy3 %>% 94 | filter(!is.na(TRTP), !is.na(BASE)) %>% 95 | group_by(TRTP, BASE) %>% 96 | complete(nesting(TRTP, BASE)) %>% 97 | summarise(N = n(), 98 | Nc = num_fmt(n(), size = 2, int_len = 2)) 99 | total_bl <- total_b %>% 100 | mutate("Shift\\line[1]" = ordered("T", c("T", "N", "H"))) %>% 101 | pivot_wider(id_cols = c("Shift\\line[1]"), names_from = c(TRTP, BASE), values_from = Nc) 102 | 103 | adlbhy_b1 <- adlbhy3 %>% 104 | group_by(TRTP, BASE, AVAL) %>% 105 | complete(nesting(BASE, AVAL)) %>% 106 | summarise(N = n()) 107 | adlbhy_b <- adlbhy_b1 %>% 108 | mutate(N2 = n_pct(N, total_b[total_b$TRTP == TRTP & 109 | total_b$BASE == BASE, "N"], n_width = 2)) %>% 110 | pivot_wider(id_cols = c("AVAL"), names_from = c("TRTP", "BASE"), values_from = c("N2")) 111 | 112 | names(adlbhy_b)[1] <- "Shift\\line[1]" 113 | 114 | total_b3 <- total_bl %>% 115 | rbind(adlbhy_b) 116 | total_b3[, " "] <- "Total Bili 1.5 x ULN and\\line Transaminase 1.5 x ULN" 117 | 118 | ## FIXME - Different counts??? 119 | # total_b3[, "p-\\line value\\line[2]"] <- c( 120 | # num_fmt(mantelhaen.test(array(unlist(adlbh_b1[,"N"]), dim = c(2,3,2)))$p.value, size = 6, int_len = 1, digits = 3) 121 | # , "", "") 122 | total_b3[, "p-\\line value\\line[2]"] <- c("", "", "") 123 | 124 | ## Table construction 125 | # Lots of weird properties for this table so I'm doing it manually 126 | comb <- rbind(total_t3, total_b3) 127 | comb <- comb[, c(8,1,2,3,4,5,6,7,9)] 128 | comb[(comb$`Shift\\line[1]` != "T"), " "] <- "" 129 | comb$`Shift\\line[1]` <- as.character(recode(comb$`Shift\\line[1]`, 130 | "T" = "n", 131 | "N" = "Normal", 132 | "Y" = "High")) 133 | comb2 <- comb %>% 134 | add_row("Shift\\line[1]" = NA, .before = 1) %>% 135 | add_row("Shift\\line[1]" = NA, .before = 1) 136 | comb2 <- comb2 %>% 137 | add_row("Shift\\line[1]" = NA, .before = 6) 138 | 139 | names(comb2) <- c( 140 | " ", 141 | "Shift\\line[1]", 142 | "Normal at Baseline", 143 | "High at Baseline", 144 | "Normal at Baseline", 145 | "High at Baseline", 146 | "Normal at Baseline", 147 | "High at Baseline", 148 | "p-\\line value\\line[2]" 149 | ) 150 | 151 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 152 | headers <- adsl %>% 153 | filter(ARM != "Screen Failure") %>% 154 | group_by(ARM) %>% 155 | summarise(N = n()) %>% 156 | mutate(label = paste0(recode(ARM, 157 | "Placebo" = "Placebo", 158 | "Xanomeline Low Dose" = "Xan. Low", 159 | "Xanomeline High Dose" = "Xan. High"), " (N=", N, ")")) 160 | 161 | ht <- comb2 %>% 162 | huxtable::as_hux(add_colnames=TRUE) 163 | 164 | ht <- as_hux(pad_row(as.data.frame(ht), c(1,1)), add_colnames = FALSE) 165 | ht[1, 3] <- headers[1, "label"] 166 | ht[1, 5] <- headers[3, "label"] 167 | ht[1, 7] <- headers[2, "label"] 168 | 169 | ht2 <- ht %>% 170 | huxtable::merge_cells(1, 3:4) %>% 171 | huxtable::merge_cells(1, 5:6) %>% 172 | huxtable::merge_cells(1, 7:8) %>% 173 | huxtable::set_bottom_border(2, 3:4, 1) %>% 174 | huxtable::set_bottom_border(2, 5:6, 1) %>% 175 | huxtable::set_bottom_border(2, 7:8, 1) %>% 176 | huxtable::set_bottom_border(3, 1:9, 1) %>% 177 | huxtable::set_width(1.5) %>% 178 | huxtable::set_escape_contents(FALSE) %>% 179 | huxtable::set_bold(1:3, 1:9, TRUE) %>% 180 | huxtable::set_valign(1:3, 1:9, "bottom") %>% 181 | huxtable::set_align(3, 1:9, "center") %>% 182 | huxtable::set_align(1, 1:9, "center") %>% 183 | huxtable::set_align(4:12, 9, "right") %>% 184 | huxtable::set_valign(10, 2:9, "bottom") %>% 185 | huxtable::set_col_width(1:9, c(0.31, rep(0.09, 7), 0.06)) 186 | 187 | # Write into doc object and pull titles/footnotes from excel file 188 | doc <- rtf_doc(ht2, header_rows = 3) %>% titles_and_footnotes_from_df( 189 | from.file='./data/titles.xlsx', 190 | reader=example_custom_reader, 191 | table_number='14-6.06') %>% 192 | set_font_size(10) %>% 193 | set_ignore_cell_padding(TRUE) %>% 194 | set_column_header_buffer(top = 1) %>% 195 | set_header_height(0.75) %>% 196 | set_footer_height(1) 197 | 198 | write_rtf(doc, file='./outputs/14-6.06.rtf') 199 | 200 | -------------------------------------------------------------------------------- /programs/t-14-7.01.R: -------------------------------------------------------------------------------- 1 | ### Table 14-7.01 Summary of Vital Signs at Baseline and End of Treatment 2 | 3 | library(huxtable) 4 | library(dplyr) 5 | library(glue) 6 | library(tidyverse) 7 | library(haven) 8 | library(pharmaRTF) 9 | library(tibble) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | 15 | pad_row <- function(df, r) { 16 | #df - dataframe to insert pad 17 | #r - row number to pad 18 | for(i in seq(along = r)) { 19 | if(r[i] + i - 1 < nrow(df)){ 20 | df[seq(r[i] + i, nrow(df) + 1),] <- df[seq(r[i] + (i - 1), nrow(df)),] 21 | df[r[i] + (i - 1),] <- NA 22 | } else { 23 | df[r[i] + (i - 1),] <- NA 24 | } 25 | } 26 | df 27 | } 28 | 29 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 30 | advs <- read_xpt(glue("{adam_lib}/advs.xpt")) %>% 31 | filter(SAFFL == "Y", ANL01FL == "Y") 32 | 33 | advs$EOTFL <- ifelse(advs[, "AVISIT"] == "End of Treatment", "Y", "") 34 | advs$W24FL <- ifelse(advs[, "AVISIT"] == "Week 24", "Y", "") 35 | 36 | advs2 <- advs %>% 37 | filter(EOTFL == "Y" | W24FL == "Y" | ABLFL == "Y") %>% 38 | filter(PARAM %in% c("Diastolic Blood Pressure (mmHg)", 39 | "Pulse Rate (beats/min)", 40 | "Systolic Blood Pressure (mmHg)")) 41 | 42 | 43 | advs2$TRTP <- ordered(advs2$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 44 | ## Add ordered VISITS to order visits 45 | advs2$AVISIT <- ordered(advs2$AVISIT, c("Baseline", "Week 24", "End of Treatment")) 46 | advs2$PARAM <- recode(advs2$PARAM, 47 | "Pulse Rate (beats/min)" = "Pulse (bpm)") 48 | advs2$PARAM <- ordered(advs2$PARAM, c("Systolic Blood Pressure (mmHg)", 49 | "Diastolic Blood Pressure (mmHg)", 50 | "Pulse (bpm)")) 51 | 52 | advs_bl <- advs2 %>% 53 | filter(ABLFL == "Y") %>% 54 | group_by(PARAM, ATPT, TRTP) %>% 55 | summarise(n = n(), 56 | mean = mean(AVAL), 57 | sd = sd(AVAL), 58 | median = median(AVAL), 59 | min = min(AVAL), 60 | max = max(AVAL)) 61 | 62 | advs_w24 <- advs2 %>% 63 | filter(W24FL == "Y") %>% 64 | group_by(PARAM, ATPT, TRTP) %>% 65 | summarise(n = n(), 66 | mean = mean(AVAL), 67 | sd = sd(AVAL), 68 | median = median(AVAL), 69 | min = min(AVAL), 70 | max = max(AVAL)) 71 | 72 | advs_eot <- advs2 %>% 73 | filter(EOTFL == "Y", !is.na(AVAL)) %>% 74 | group_by(PARAM, ATPT, TRTP) %>% 75 | summarise(n = n(), 76 | mean = mean(AVAL), 77 | sd = sd(AVAL), 78 | median = median(AVAL), 79 | min = min(AVAL), 80 | max = max(AVAL)) 81 | 82 | advs3 <- rbind(advs_bl, advs_w24, advs_eot) %>% 83 | arrange(PARAM, ATPT, TRTP) %>% 84 | add_column("PRTFL" = rep(c("Baseline", "Week 24", "End of Trt."), 27), .before = 4) 85 | 86 | 87 | advs4 <- add_column(advs3, "N" = apply(advs3, 88 | 1, 89 | function(x) {aSum <- sum(adsl[,"ARM"] == x["TRTP"], na.rm = TRUE) 90 | ifelse(aSum == 0, NA, aSum)}), 91 | .after = 3) 92 | 93 | advs4[!(advs4$PRTFL %in% "Baseline"), "TRTP"] <- NA 94 | advs4[!(advs4$TRTP %in% "Placebo"), "ATPT"] <- NA 95 | advs4[!(advs4$ATPT %in% "AFTER LYING DOWN FOR 5 MINUTES"), "PARAM"] <- NA 96 | advs4[!(advs4$PRTFL %in% "Baseline"), "N"] <- NA 97 | 98 | 99 | 100 | advs4$TRTP <- apply(advs4, 1, function(x) {switch(x["TRTP"], 101 | "Placebo" = "Placebo", 102 | "Xanomeline High Dose" = "Xan.High", 103 | "Xanomeline Low Dose" = "Xan.Low", 104 | NA)}) 105 | 106 | advs4$mean <- num_fmt(advs4$mean, digits = 1, size = 4) 107 | advs4$sd <- num_fmt(advs4$sd, digits = 2, size = 5, int_len = 2) 108 | advs4$median <- num_fmt(advs4$median, digits = 1, size = 4, int_len = 3) 109 | advs4$min <- num_fmt(advs4$min, digits = 1, size = 4, int_len = 3) 110 | advs4$max <- num_fmt(advs4$max, digits = 1, size = 4, int_len = 3) 111 | 112 | 113 | names(advs4) <- c( 114 | "Measure", 115 | "Position", 116 | "Treatment", 117 | "N", 118 | "Planned Relative Time", 119 | "n", 120 | "Mean", 121 | "SD", 122 | "Median", 123 | "Min.", 124 | "Max." 125 | ) 126 | 127 | advs4 <- pad_row(advs4, which(advs4[, "Planned Relative Time"] == "End of Trt.") + 1) 128 | 129 | ht <- advs4 %>% 130 | huxtable::as_hux(add_colnames=TRUE) %>% 131 | huxtable::set_bold(1, 1:ncol(advs4), TRUE) %>% 132 | huxtable::set_align(1, 1:ncol(advs4), "center") %>% 133 | huxtable::set_align(2:nrow(advs4), 3, "center") %>% 134 | huxtable::set_align(2:nrow(advs4), 4:ncol(advs4), "left") %>% 135 | huxtable::set_valign(1, 1:ncol(advs4), "bottom") %>% 136 | huxtable::set_bottom_border(1, 1:ncol(advs4), 1) %>% 137 | huxtable::set_width(1.45) %>% 138 | huxtable::set_col_width(1:ncol(advs4), c(0.2, 0.15, 0.19, 0.03, 0.1, 0.03, 0.06, 0.06, 0.06, 0.06, 0.06)) 139 | 140 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 141 | from.file='./data/titles.xlsx', 142 | reader=example_custom_reader, 143 | table_number='14-7.01') %>% 144 | set_font_size(10) %>% 145 | set_ignore_cell_padding(TRUE) %>% 146 | set_header_height(1) %>% 147 | set_column_header_buffer(1,0) %>% 148 | set_footer_height(1.4) 149 | 150 | write_rtf(doc, file='./outputs/14-7.01.rtf') 151 | 152 | 153 | -------------------------------------------------------------------------------- /programs/t-14-7.02.R: -------------------------------------------------------------------------------- 1 | ## Table 14-7.02 Summary of Vital Signs Change from Baseline at End of Treatment 2 | 3 | library(huxtable) 4 | library(dplyr) 5 | library(glue) 6 | library(tidyverse) 7 | library(haven) 8 | library(pharmaRTF) 9 | library(tibble) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | 15 | pad_row <- function(df, r) { 16 | #df - dataframe to insert pad 17 | #r - row number to pad 18 | for(i in seq(along = r)) { 19 | if(r[i] + i - 1 < nrow(df)){ 20 | df[seq(r[i] + i, nrow(df) + 1),] <- df[seq(r[i] + (i - 1), nrow(df)),] 21 | df[r[i] + (i - 1),] <- NA 22 | } else { 23 | df[r[i] + (i - 1),] <- NA 24 | } 25 | } 26 | df 27 | } 28 | 29 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 30 | advs <- read_xpt(glue("{adam_lib}/advs.xpt")) %>% 31 | filter(SAFFL == "Y" & !is.na(BASE)) 32 | 33 | advs$EOTFL <- ifelse(advs[,"AVISIT"] == "End of Treatment", "Y", "") 34 | advs$W24FL <- ifelse(advs[, "AVISIT"] == "Week 24", "Y", "") 35 | 36 | advs2 <- advs %>% 37 | filter(EOTFL == "Y" | W24FL == "Y") %>% 38 | filter(PARAM %in% c("Diastolic Blood Pressure (mmHg)", 39 | "Pulse Rate (beats/min)", 40 | "Systolic Blood Pressure (mmHg)")) 41 | 42 | advs2$PRTFL <- ifelse(advs2[,"EOTFL"] == "Y", "End of Trt.","Week 24") 43 | 44 | advs2$TRTP <- ordered(advs2$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 45 | ## Add ordered VISITS to order visits 46 | advs2$AVISIT <- ordered(advs2$AVISIT, c("Baseline", "Week 24", "End of Treatment")) 47 | advs2$PRTFL <- ordered(advs2$PRTFL, c("Week 24", "End of Trt.")) 48 | advs2$PARAM <- recode(advs2$PARAM, 49 | "Pulse Rate (beats/min)" = "Pulse (bpm)") 50 | advs2$PARAM <- ordered(advs2$PARAM, c("Systolic Blood Pressure (mmHg)", 51 | "Diastolic Blood Pressure (mmHg)", 52 | "Pulse (bpm)")) 53 | 54 | advs3 <- advs2 %>% 55 | group_by(PARAM, ATPT, TRTP, PRTFL) %>% 56 | summarise(n = n(), 57 | mean = mean(CHG, na.rm = TRUE), 58 | sd = sd(CHG, na.rm = TRUE), 59 | median = median(CHG, na.rm = TRUE), 60 | min = min(CHG, na.rm = TRUE), 61 | max = max(CHG, na.rm = TRUE)) 62 | 63 | advs4 <- add_column(advs3, "N" = apply(advs3, 64 | 1, 65 | function(x) {aSum <- sum(adsl[,"ARM"] == x["TRTP"], na.rm = TRUE) 66 | ifelse(aSum == 0, NA, aSum)}), 67 | .after = 3) 68 | 69 | advs4[!(advs4$PRTFL %in% "Week 24"), "TRTP"] <- NA 70 | advs4[!(advs4$TRTP %in% "Placebo"), "ATPT"] <- NA 71 | advs4[!(advs4$ATPT %in% "AFTER LYING DOWN FOR 5 MINUTES"), "PARAM"] <- NA 72 | advs4[!(advs4$PRTFL %in% "Week 24"), "N"] <- NA 73 | 74 | 75 | 76 | advs4$TRTP <- apply(advs4, 1, function(x) {switch(x["TRTP"], 77 | "Placebo" = "Placebo", 78 | "Xanomeline High Dose" = "Xan.High", 79 | "Xanomeline Low Dose" = "Xan.Low", 80 | NA)}) 81 | 82 | advs4$mean <- num_fmt(advs4$mean, digits = 1, size = 3) 83 | advs4$sd <- num_fmt(advs4$sd, digits = 2, size = 4, int_len = 2) 84 | advs4$median <- num_fmt(advs4$median, digits = 1, size = 2, int_len = 2) 85 | advs4$min <- num_fmt(advs4$min, digits = 1, size = 4, int_len = 2) 86 | advs4$max <- num_fmt(advs4$max, digits = 1, size = 4, int_len = 2) 87 | 88 | 89 | names(advs4) <- c( 90 | "Measure", 91 | "Position", 92 | "Treatment", 93 | "N", 94 | "Planned Relative Time", 95 | "n", 96 | "Mean", 97 | "SD", 98 | "Median", 99 | "Min.", 100 | "Max." 101 | ) 102 | 103 | advs4 <- pad_row(advs4, which(advs4[, "Planned Relative Time"] == "End of Trt.") + 1) 104 | 105 | ht <- advs4 %>% 106 | huxtable::as_hux(add_colnames=TRUE) %>% 107 | huxtable::set_bold(1, 1:ncol(advs4), TRUE) %>% 108 | huxtable::set_align(1, 1:ncol(advs4), "center") %>% 109 | huxtable::set_align(2:nrow(advs4), 3, "center") %>% 110 | huxtable::set_align(2:nrow(advs4), 4:ncol(advs4), "left") %>% 111 | huxtable::set_valign(1, 1:ncol(advs4), "bottom") %>% 112 | huxtable::set_bottom_border(1, 1:ncol(advs4), 1) %>% 113 | huxtable::set_width(1.45) %>% 114 | huxtable::set_col_width(1:ncol(advs4), c(0.2, 0.15, 0.19, 0.03, 0.1, 0.03, 0.06, 0.06, 0.06, 0.06, 0.06)) 115 | wrap(ht) <- FALSE 116 | 117 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 118 | from.file='./data/titles.xlsx', 119 | 120 | reader=example_custom_reader, 121 | table_number='14-7.02') %>% 122 | set_font_size(10) %>% 123 | set_ignore_cell_padding(TRUE) %>% 124 | set_header_height(1) %>% 125 | set_column_header_buffer(1,0) %>% 126 | set_footer_height(1.3) 127 | 128 | write_rtf(doc, file='./outputs/14-7.02.rtf') 129 | 130 | -------------------------------------------------------------------------------- /programs/t-14-7.03.R: -------------------------------------------------------------------------------- 1 | ### Table 14-7.03 pg 148 Summary of Weight Change from Baseline at End of Treatment 2 | 3 | 4 | library(dplyr) 5 | library(glue) 6 | library(tidyverse) 7 | library(haven) 8 | library(assertthat) 9 | library(pharmaRTF) 10 | library(tibble) 11 | 12 | 13 | source('./programs/config.R') 14 | source('./programs/funcs.R') 15 | 16 | n_pct <- function(n, pct, n_width=3, pct_width=3) { 17 | n <- unlist(n) 18 | pct <- unique(pct) 19 | # n (%) formatted string. e.g. 50 ( 75%) 20 | unlist(lapply(n, function(x) { 21 | if(x == 0) " 0 " 22 | else { 23 | as.character( 24 | # Form the string using glue and format 25 | glue('{format(x, width=n_width)}({format(round((x/pct) * 100), width=pct_width)}%)') 26 | ) 27 | } 28 | })) 29 | } 30 | 31 | advs <- read_xpt(glue("{adam_lib}/advs.xpt")) %>% 32 | filter(PARAM == "Weight (kg)") 33 | 34 | advs$TRTP <- ordered(advs$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 35 | 36 | advs$EOTFL <- ifelse(advs$AVISITN == 99, "Y", NA) 37 | advs$W24 <- ifelse(advs$AVISITN == 24, "Y", NA) 38 | advs$ABLFL <- ifelse(advs$ABLFL == "Y", "Y", NA) 39 | 40 | #Rbinded data.frame 41 | advs2 <- rbind(advs[advs$EOTFL %in% "Y", ], advs[advs$W24 %in% "Y",], advs[advs$ABLFL %in% "Y",]) 42 | 43 | # Create table for stats 44 | bw_stats <- advs2 %>% 45 | group_by(TRTP, ABLFL, W24, EOTFL) %>% 46 | summarise(n = n(), 47 | Mean = mean(AVAL), 48 | SD = sd(AVAL), 49 | Median = median(AVAL), 50 | Min. = min(AVAL), 51 | Max. = max(AVAL)) %>% 52 | arrange() 53 | bw_stats[, 2] <- rep(c("Baseline", "Week 24", "End of Trt."), 3) 54 | bw_stats <- bw_stats[, c(-3, -4)] 55 | 56 | bw_stats <- add_column(bw_stats, "Measure" = "Weight (kg)", .before= 1) 57 | bw_stats[unlist(bw_stats[, 3]) != "Baseline", "TRTP"] <- NA 58 | bw_stats[!(bw_stats$TRTP %in% "Placebo"), "Measure"] <- NA 59 | 60 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 61 | bw_stats <- add_column(bw_stats, "N" = apply(bw_stats, 62 | 1, 63 | function(x) {aSum <- sum(adsl[,"ARM"] == x["TRTP"], na.rm = TRUE) 64 | ifelse(aSum == 0, NA, aSum)}), 65 | .before = 3) 66 | # Pad blank rows after End of Trt. rows 67 | pad_row <- function(df, r) { 68 | #df - dataframe to insert pad 69 | #r - row number to pad 70 | for(i in seq(along = r)) { 71 | if(r[i] + i - 1 < nrow(df)){ 72 | df[seq(r[i] + i, nrow(df) + 1),] <- df[seq(r[i] + (i - 1), nrow(df)),] 73 | df[r[i] + (i - 1),] <- NA 74 | } else { 75 | df[r[i] + (i - 1),] <- NA 76 | } 77 | } 78 | df 79 | } 80 | bw_stats <- pad_row(bw_stats, which(bw_stats$ABLFL == "End of Trt.",) + 1) 81 | names(bw_stats)[4] <- "VISIT" 82 | 83 | 84 | ### Weight Change from Baseline table 85 | # Create table for baseline changes 86 | 87 | 88 | .blfun = function(x, usubjid = NULL) { 89 | x <- x[x$USUBJID == unique(usubjid),] 90 | bl <- as.numeric(x[x$ABLFL %in% "Y", "AVAL"]) 91 | w24 <- as.numeric(x[x$W24 %in% "Y", "AVAL"]) 92 | eot <- as.numeric(x[x$EOTFL %in% "Y", "AVAL"]) 93 | arm <- unique(x$TRTP) 94 | ## Done this way to make dplyr easier 95 | c(ifelse(length(w24-bl) == 0, NA, w24-bl), 96 | ifelse(length(eot-bl) == 0, NA, eot-bl)) 97 | } 98 | bw_bl <- advs2 %>% 99 | select(USUBJID, TRTP, ABLFL, W24, EOTFL, AVAL) %>% 100 | group_by(USUBJID) %>% 101 | summarise(`WEEK 24` = .blfun(., USUBJID)[1], 102 | `End of Trt.` = .blfun(., USUBJID)[2], 103 | TRTP = unique(TRTP)) %>% 104 | select(USUBJID, TRTP, `WEEK 24`, `End of Trt.`) %>% 105 | pivot_longer(c(`WEEK 24`, `End of Trt.`), names_to = "VISIT", values_to = "change") 106 | ## Add ordered factor to order arms 107 | bw_bl$TRTP <- ordered(bw_bl$TRTP, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 108 | bw_bl$VISIT <- ordered(bw_bl$VISIT,c("WEEK 24", "End of Trt.")) 109 | 110 | bw_bl_1 <- bw_bl %>% 111 | group_by(TRTP, VISIT) %>% 112 | summarise(n = sum(!is.na(change)), 113 | Mean = mean(change, na.rm = TRUE), 114 | SD = sd(change, na.rm = TRUE), 115 | Median = median(change, na.rm = TRUE), 116 | Min. = min(change, na.rm = TRUE), 117 | Max. = max(change, na.rm = TRUE)) %>% 118 | ungroup() 119 | bw_bl_1 <- add_column(bw_bl_1, "Measure" = "Weight Change\\line from Baseline", .before = 1) 120 | bw_bl_1[bw_bl_1$VISIT != "WEEK 24", "TRTP"] <- NA 121 | bw_bl_1[!(bw_bl_1$TRTP %in% "Placebo"), "Measure"] <- NA 122 | 123 | bw_bl_1 <- add_column(bw_bl_1, "N" = apply(bw_bl_1, 124 | 1, 125 | function(x) {aSum <- sum(adsl[,"ARM"] == x["TRTP"], na.rm = TRUE) 126 | ifelse(aSum == 0, NA, aSum)}), 127 | .before = 3) 128 | bw_bl_1 <- pad_row(bw_bl_1, which(bw_bl_1$VISIT == "End of Trt.") + 1) 129 | 130 | ### Combine Tables and match output 131 | combinedTable <- rbind(bw_stats, bw_bl_1) 132 | names(combinedTable)[2] <- "Treatment" 133 | names(combinedTable)[4] <- "Planned Relative Time" 134 | combinedTable[,"Treatment"] <- apply(combinedTable, 1, function(x){ 135 | switch(x["Treatment"], 136 | "Placebo" = "Placebo", 137 | "Xanomeline Low Dose" = "Xan.Low", 138 | "Xanomeline High Dose" = "Xan.High", 139 | NA) 140 | }) 141 | combinedTable[,"Planned Relative Time"] <- apply(combinedTable, 1, function(x){ 142 | switch(x["Planned Relative Time"], 143 | "Baseline" = "Baseline", 144 | "WEEK 24" = "Week 24", 145 | "Week 24" = "Week 24", 146 | "End of Trt." = "End of Trt.", 147 | NA) 148 | }) 149 | 150 | ### Number formatting 151 | class(combinedTable) <- "data.frame" 152 | combinedTable[!is.na(combinedTable$Mean),"Mean"] <- num_fmt(unlist(combinedTable[!is.na(combinedTable$Mean),"Mean"]), 153 | digits = 1, size = 3, int_len = 2) 154 | combinedTable[!is.na(combinedTable$SD),"SD"] <- num_fmt(unlist(combinedTable[!is.na(combinedTable$SD),"SD"]), 155 | digits = 2, size = 3, int_len = 2) 156 | combinedTable[!is.na(combinedTable$Median),"Median"] <- num_fmt(unlist(combinedTable[!is.na(combinedTable$Median),"Median"]), 157 | digits = 1, size = 3, int_len = 2) 158 | combinedTable[!is.na(combinedTable$`Min.`),"Min."] <- num_fmt(unlist(combinedTable[!is.na(combinedTable$`Min.`),"Min."]), 159 | digits = 1, size = 3, int_len = 2) 160 | combinedTable[!is.na(combinedTable$`Max.`),"Max."] <- num_fmt(unlist(combinedTable[!is.na(combinedTable$`Max.`),"Max."]), 161 | digits = 1, size = 3, int_len = 2) 162 | 163 | 164 | ht <- combinedTable %>% 165 | huxtable::as_hux(add_colnames=TRUE) 166 | 167 | 168 | huxtable::bottom_border(ht)[1, ] <- 1 169 | huxtable::bold(ht)[1, ] <- TRUE 170 | huxtable::align(ht)[1, ] <- 'center' 171 | huxtable::align(ht)[,c(3, 5:10)] <- "center" 172 | huxtable::width(ht) <- 1.5 173 | huxtable::bottom_padding(ht) <- 0 174 | huxtable::top_padding(ht) <- 0 175 | huxtable::col_width(ht) <- c(0.25, 0.15, 0.05, 0.185, 0.04, 0.065, 0.065, 0.065, 0.065, 0.065) 176 | huxtable::valign(ht)[1,] <- "bottom" 177 | huxtable::escape_contents(ht) <- FALSE 178 | 179 | 180 | 181 | # Write into doc object and pull titles/footnotes from excel file 182 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 183 | from.file='./data/titles.xlsx', 184 | reader=example_custom_reader, 185 | table_number='14-7.03') %>% 186 | set_font_size(10) %>% 187 | set_ignore_cell_padding(TRUE) %>% 188 | set_header_height(1) %>% 189 | set_column_header_buffer(1,0) 190 | 191 | write_rtf(doc, file='./outputs/14-7.03.rtf') 192 | 193 | -------------------------------------------------------------------------------- /programs/t-14-7.04.R: -------------------------------------------------------------------------------- 1 | ### Table 14-7.01: Summary of Concomitant Medications (Number of Subjects) 2 | 3 | library(dplyr) 4 | library(glue) 5 | library(tidyverse) 6 | library(haven) 7 | library(assertthat) 8 | library(pharmaRTF) 9 | library(tibble) 10 | 11 | source('./programs/config.R') 12 | source('./programs/funcs.R') 13 | 14 | ## Modified n_pct function 15 | n_pct <- function(n, pct) { 16 | # n (%) formatted string. e.g. 50 ( 75%) 17 | return( 18 | # Suppress conversion warnings 19 | as.character( 20 | # Form the string using glue and format 21 | glue('{format(n, width=3)} ({format(round((n/pct) * 100))}%)') 22 | ) 23 | ) 24 | } 25 | 26 | 27 | cm <- read_xpt(glue("{sdtm_lib}/cm.xpt")) 28 | adsl <- read_xpt(glue("{adam_lib}/adsl.xpt")) 29 | adsl$ARM <- ordered(adsl$ARM, c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose")) 30 | 31 | ## Patients receiving at least one medication 32 | cm_1 <- adsl %>% 33 | group_by(ARM) %>% 34 | summarise(n = sum(USUBJID %in% unique(cm$USUBJID)), 35 | total = n()) 36 | cm_res <- n_pct(cm_1$n, cm_1$total) 37 | 38 | cm_2 <- data.frame( 39 | "Therapeutic class, n (%)" = "Patients receiving at least one concomitant medication", 40 | "Placebo" = cm_res[1], 41 | "Xanomeline Low Dose" = cm_res[2], 42 | "Xanomeline High Dose" = cm_res[3], 43 | stringsAsFactors = FALSE, check.names = FALSE, row.names = FALSE 44 | ) 45 | 46 | ### Table 47 | # Medication classes 48 | cm_class <- sort(unique(cm$CMCLAS)) 49 | 50 | # By Class 51 | df <- plyr::ldply(cm_class, function(class_i){ 52 | class_by_arm <- as.data.frame(adsl %>% 53 | group_by(ARM) %>% 54 | summarise(n = sum(USUBJID %in% unlist(unique(cm[cm$CMCLAS == class_i, "USUBJID"]))))) 55 | 56 | df_1 <- data.frame( 57 | "Therapeutic class, n (%)" = class_i, 58 | "Placebo" = unname(ifelse(class_by_arm[1, "n"] == 0, " 0", n_pct(class_by_arm[1, "n"], cm_1[1, "total"]))), 59 | "Xanomeline Low Dose" = unname(ifelse(class_by_arm[2, "n"] == 0, " 0", n_pct(class_by_arm[2, "n"], cm_1[2, "total"]))), 60 | "Xanomeline High Dose" = unname(ifelse(class_by_arm[3, "n"] == 0, " 0", n_pct(class_by_arm[3, "n"], cm_1[3, "total"]))), 61 | stringsAsFactors = FALSE, check.names = FALSE, row.names = FALSE 62 | ) 63 | 64 | #Pad Row 65 | df_1 <- add_row(df_1, "Therapeutic class, n (%)" = "", .before = 1) 66 | 67 | #Coded medication names 68 | cm_medi <- unlist(unique(cm[cm$CMCLAS == class_i, "CMDECOD"]), use.names = FALSE) 69 | 70 | #By Medication 71 | df_2 <- plyr::ldply(cm_medi, function(medi_i) { 72 | 73 | medi_by_arm <- as.data.frame(adsl %>% 74 | group_by(ARM) %>% 75 | summarise(n = sum(USUBJID %in% unlist(unique(cm[cm$CMDECOD == medi_i, "USUBJID"]))))) 76 | 77 | 78 | df_3 <- data.frame( 79 | "Therapeutic class, n (%)" = paste0("\t", unname(medi_i)), 80 | "Placebo" = unname(ifelse(medi_by_arm[1, "n"] == 0, " 0", n_pct(medi_by_arm[1, "n"], cm_1[1, "total"]))), 81 | "Xanomeline Low Dose" = unname(ifelse(medi_by_arm[2, "n"] == 0, " 0", n_pct(medi_by_arm[2, "n"], cm_1[2, "total"]))), 82 | "Xanomeline High Dose" = unname(ifelse(medi_by_arm[3, "n"] == 0, " 0", n_pct(medi_by_arm[3, "n"], cm_1[3, "total"]))), 83 | stringsAsFactors = FALSE, check.names = FALSE, row.names = FALSE 84 | ) 85 | }) 86 | ## Order Medications. Order Descending by placebo count and ascending alphabetically 87 | # radix used because its the only method that supports a decreasing vector. 88 | df_2 <- df_2[order(df_2$Placebo, df_2[,1], decreasing = c(TRUE, FALSE), method = "radix"),] 89 | rbind(df_1, df_2) 90 | }) 91 | 92 | 93 | combinedTable <- rbind(cm_2, df) 94 | 95 | 96 | ### Add Headers 97 | headers <- adsl %>% 98 | group_by(ARM) %>% 99 | summarise(N = n()) %>% 100 | mutate(labels = str_replace_all(str_wrap(glue('{ARM} (N={N})'), width=10), "\n", function(x) "\\line ")) 101 | names(combinedTable) <- c("Therapeutic class, n (%)", headers$labels) 102 | 103 | 104 | ht <- combinedTable %>% 105 | huxtable::as_hux(add_colnames=TRUE) 106 | 107 | 108 | huxtable::bottom_border(ht)[1, ] <- 1 109 | huxtable::bold(ht)[1, ] <- TRUE 110 | huxtable::align(ht)[1, ] <- 'center' 111 | huxtable::align(ht)[1, 1] <- "left" 112 | huxtable::width(ht) <- 1.2 113 | huxtable::bottom_padding(ht) <- 0 114 | huxtable::top_padding(ht) <- 0 115 | huxtable::col_width(ht) <- c(.6, .15, .15, .15) 116 | huxtable::valign(ht)[1,] <- "bottom" 117 | huxtable::escape_contents(ht) <- FALSE 118 | huxtable::align(ht)[-1,2:4] <- "left" 119 | 120 | 121 | 122 | 123 | # Write into doc object and pull titles/footnotes from excel file 124 | doc <- rtf_doc(ht) %>% titles_and_footnotes_from_df( 125 | from.file='./data/titles.xlsx', 126 | reader=example_custom_reader, 127 | table_number='14-7.04') %>% 128 | set_font_size(10) %>% 129 | set_ignore_cell_padding(TRUE) %>% 130 | set_header_height(1) %>% 131 | set_column_header_buffer(1,0) %>% 132 | set_footer_height(1) 133 | 134 | write_rtf(doc, file='./outputs/14-7.04.rtf') 135 | 136 | --------------------------------------------------------------------------------