 Hello, I'm Stefan Kedaki, chair of the conference and co-moderator of this session, and I'm very pleased to introduce my friend and colleague Peter Higgins. Peter is a professor of medicine at U Michigan, where his day job is performing endoscopies and taking care of patients with inflammatory bowel disease. Peter is actually a fixture of our medicine has been giving presentations each year of the conference so far. And he's a member of this year's organizing and program committees. Take it away, Peter. Thank you, Stefan. For those of you who've been impressed by the skills and packages of Will, Vincent, Karthik, Travis, and Garrick, this will make you feel better. If you're having a little bit of imposter syndrome, I'll help you feel better. But it's a great example of biting off a little more than you can chew, but I think it's an interesting project that is really a work in progress, not a finished package. So for those of you who don't know, consort diagrams are to promote transparency in reporting of clinical trials and basically start with the patients assessed for eligibility and follow them through each step in the trial from randomization, completion, dosing with drug. And anytime someone doesn't complete, you have to provide the reasons why they didn't complete the study. And this was developed in 1993, the most recent version in 2010 is now the standard for reporting clinical trials. There is a website. There is a standard diagram in RTF template, but that's about it. There's no underlying data structure or best practices for building a consort diagram. So it's sort of becoming an artisanal product built by counting categories and then copying and pasting the results into templates. This leads to frequent errors in which the participant notice and numbers don't add up. And it's a great gotcha for reviewers. But it should be reproducible and ideally there'd be a programmatic way to do this. And I got involved in this idea when I decided to just see if I could draw a consort diagram in GG plot two and ended up coming up with a version that I put on our pubs. And to my surprise, other people saw it, googled it because there's not much else about building consort diagrams in R and you can actually do this. Now, this is making a simple grid, adding boxes. And you can see from the code here that this is really done artisanally counting and pasting things in. So it's not really programmatic, but essentially you can add your boxes and arrows, all your randomization, and by ending up with theme void, you can end up with a pretty nice looking consort diagram. And this is where I got a little bit overconfident and decided, yeah, I can do this. I can make this programmatic because it's not reproducible. But I'd like to get to that point. And the goal is to end up with something like a function, like draw consort, and an argument that's a status table, a standard data table that you can use to extract all this information. And ideally it worked with any number of arms. It would have nice text wrapping so the boxes don't get too wide. And fit boxes to the appropriate height and width of text, draw the lines and arrows to the right places, set spacing appropriately between boxes and lines, and draw the diagram. But the problem is there isn't a clear underlying data structure, and this is where I spent some time trying to think about this in March when Michigan was pretty much shut down. And it immediately occurs that there are two different parts of the consort diagram. There's the top section where you basically have one of everything, assessment, randomization, and exclusion. And then the bottom section where the number of things is related to the number of arms. So you have assignment boxes, five for a five-arm study, discontinued boxes, completion boxes, and the appropriate arrows, all number equal to n arms. I also said this crossbar here is at y equals zero, and it's centered at x equals zero to make the locations a little bit easier. Then I went through and named and numbered everything so I could organize it, but clearly there's two distinct things going on, things where you draw one of something or things where you draw n arms of something. And essentially, I wanted to build a status table where you have one row per candidate participant with their status at each step of the study as a column. This includes both randomized participants and the candidate participants who end up being excluded, also known as screen failures. In the columns, you can include a study ID which helps you check your data, but essentially randomized in the exclusion region, and these generally come in pairs. So if they're randomized, they should have an NA for their exclusion region, or if they're not randomized, they should have an NA and then a text for their exclusion region. And that helps check and cross validate the data so you're making sure that you don't have somebody who's listed as randomized and has an exclusion region. Same with receive their intervention or didn't receive, completed and discontinued, analyzed and not analyzed. So I then built examples from actual clinical trials numbered by the number of arms, and the first four are ones I participated in. And then I googled PubMed to find one that had eight arms, just as another sort of outlier example, and built these out as status tables. And here's a glimpse of what, here's a two-arm status table that we did for post-ERCP pancreatitis, and it gives you an idea of what this looks like, basically either you have a yes or an NA or peck text if you have someone who didn't receive the intervention. So the conceptual model is that you start out, and this is the top table, with three boxes, assessment, exclusion, and randomization. The assessment is essentially you count a number and then glue it to some text, same with the randomization, whereas the exclusion box, because there are multiple exclusions, is essentially a mini table that gets collapsed into a single string. But once you have that, you can count the maximum width in characters, the height in the number of lines, and then convert those to the dimensions of the box that you need for X min, X max, Y min, and Y max. And then you can do the same for the corresponding arrows, where they need to go with X, X and Y and YN. Once you have this table, you can plot the boxes with GMRECT, the labels with GM text, and the arrows with GM segment in one call. The bottom table is a little bit more complicated, but it largely works the same way. I'm just showing the assignment rows from this five-arm study, so they number from 51 to 55, they're named appropriately. Their location, because this one's in the center, I'm calling this 0 for X equals 0. The one at the far left is negative 2, the one at far right is 2. Each one has a label with maximum character and lines, dimensions of the box, dimensions of the appropriate arrow, and you GG plot them systematically the same way. I built out several of the helper functions, the count arms and list arms, for the individual labels, you filter and count and glue to the text for each box. For the more complex labels, the mini tables, essentially you're counting the exclusion reasons, building a mini table, adding a total row, moving that to the top and collapsing that to a text string with new lines. Right now that doesn't handle zeros well if there are no discontinuations in one arm. Essentially we're in good shape for building the top table and building the bottom table is close, but it's not quite. There's some mapping issues with per map. Fundamentally as I was going through this, I realized while it was a fun project to take on, I really don't know enough about GG plot internals. It's hard to consistently convert character width to X values on a GG plot and lines into Y values on the GG plot. As I add more rows of boxes, the self-adjusting GG plot size shrinks the previous boxes so the labels are a little bit bigger than the boxes. It might be easier with the GG text package and that I've been experimenting with that a little bit, but it doesn't return values for its box location. So it's a little bit hard to draw the arrows to the right place. And then facing the reality of actually trying to build whole package with this, with tasks, documentation, a package down a website, this is way beyond what I've ever done. It seems unlikely I can maintain a package alone, helps really need it. And this is where I need help from our community. First aspirationally, I've got a repository with some functions and a really crude package down website. And of course, an aspirational hex sticker because if you have a cool hex sticker, you're committed to finish. But bottom line, this is a proof of concept, not a proper package. It needs tests, especially on status table input. This is something which needs people who know what they're doing. So if folks are working in the chat, if you want to send out contact info, I would love to have more help. I'm not sure if I get it to work in a Mac OS in our studio, if it'll work across all graphics devices. That's an area I haven't explored at all. I would love to add helper functions to take standard data format like SDGTM and add them to pull those and make those status tables so then you can pipe them right into draw a consort. A little bit more ability to work with data in the wild, not quite so curated data, obviously useful vignettes as Travis was saying, documentation, a package down site, and essentially some customization. Currently it's only set to work with the defaults, nothing else. So bottom line, thanks for your help. Anybody who's interested in this who think it would be valuable would love to get any help I can get. When I see Abhijit suggesting Diagrammer, I played with Diagrammer a lot in March. It doesn't quite work. There are a couple of issues with it. That drawing the arrows is problematic, its default is curved. It may be worth talking to Rich. I pinged him a couple of times, so I didn't get a whole lot back, but currently the way Diagrammer is built, it doesn't make a consort diagram very well. Thank you very much for this presentation. It was, I think it went well. And I'm going to move us then to the next session.