and I'm presenting today with Rebecca Lyzinski.
We're going to be talking about
how we use Graph Builder and Tabulate in applications
for visualizing data from clinical trials.
We have a product called JMP Clinical,
and it's a focused and specialized product for clinical trial data review.
We give users straight out of the box
functionality to do a thorough review
of clinical trials at the study site and subject level.
It is a product that's used across the pharmaceutical industry
and at several regulatory agencies across the world.
It's built on top of JMP Pro, utilizing JMP scripting language,
and it provides a user interface for data management, configuration,
and standardized reports.
We utilize data standards as part of JMP Clinical.
We utilize the CDISC study data tabulation model
and analysis data model as required input formats
for the data that you're going to visualize.
This allows us then to develop standardized tools.
In general,
if you want to develop standardized tools,
having a data standard to follow for the input data
really enables you to do that.
We use Graph Builder and Tabulate
across almost all of our reports that we have in JMP Clinical.
We want to show you how we create the graphs
that we use in JMP Clinical
so you can learn more about these important platforms,
Tabulate and Graph Builder,
and how you could use them for your analysis work
and if you wanted to make standardized reports yourself.
We're going to show you
several of the analysis reports that we have in JMP Clinical:
our adverse events distribution that utilizes Graph Builder and Tabulate,
our adverse events risk report, which uses a multipanel Graph Builder
that also utilizes virtual joins between data tables,
and it applies some data filters.
We also are going to show you our findings time trend result,
which also uses a complicated graph builder,
a column switching and virtual joins.
Then we'll finish up
by showing you an adva nced-level collection of graph builders
that we use for our patient profiles.
One of our most popular reports is the Adverse Event Distribution Report.
This report shows a bar chart at the top and a tabulate underneath it.
The bar chart has dictionary- derived term on the X- axis,
which is a way of grouping adverse events,
and planned treatment group on the Y- axis.
Each bar represents a count of the adverse events
for a given dictionary-derived term.
Underneath we have a tabulate
that is also showing dictionary-derived term,
but it also groups the adverse events by body system or organ class.
We have two different grouping variables.
The columns represent one column for each treatment group,
one for Nicardipine in the study, and another for placebo,
as well as a total column.
The ends represent counts
and the percents are the percents of subjects with an adverse event.
Down at the bottom, there's an all row,
which represents any subject that had an adverse event in the given column.
For example, we have 882 subjects in this study
that had at least one adverse event.
One of the options that JMP Clinical includes
is a way to stack the bar chart in the table.
For example, you can stack by severity or intensity.
This creates a stacked bar chart with green bars representing mild events,
yellow for moderate, and red for severe.
It also splits out the table by mild, moderate, and severe events.
In order to recreate these, we can pop out the data table.
For the graph, we go to Graph and Graph Builder.
We select our planned treatment group and put that on the group Y.
Make this a little bigger.
There are a lot of columns in this data table,
so we're going to search for dictionary-derived term
and we'll grab that and place it on the X- axis.
This is pretty close to what's on the report,
except for the ordering.
If you right-click on the X-axis and go to, Order By,
we can select Count Descending,
and now it's ordered the same way that it was in the report.
If we want to also add that stacking, we can search for severity
and drag that variable over to the overlay.
That gets us close to what we saw, but the bars are stacked side-by-side.
In order to change that, we can go to the control panel
and instead of side-by-side, select Stacked for bar style.
Now we're back to our original graph.
Next, if we want to recreate the tabulate, we go to Analyze Tabulate.
Again, select Plan Treatment Group for our columns.
This time we're going to select dictionary-derived term
and put that in the first grouping column.
But we also want to select Body System or Organ Class
and put that as a grouping column as well.
By default, they show up as two separate columns.
We're going to select both columns,
right-click and go to Stack Group and Columns.
That allows them to both be concatenated into one column.
To add to our table,
we are going to drag the little N over underneath our treatment group
so that we get our counts and the percent next to the N.
By default, these are two separate columns.
In order to create one column, we're going to first drag the sum up above
so that Tabulate knows both the N and percent are supposed to be sums.
We again select both columns and right-click.
Under Pack Columns, go to Pack.
Now we see the account and the percent in one column.
The percent has no formatting on the number of decimal places.
If we go to Change Format and go to the percent,
we can change from best to one decimal place.
Now we have a better formatted table.
One other thing that's missing is we have a group N
that we're going to stick underneath our treatment groups.
That way we can see how many subjects were in each treatment group.
You'll also notice by default
that these rows for the body system organ class are missing values.
In order to fill those in,
we're going to select Add Aggregate Statistics.
Now all our values have been filled in.
Now we just need to do a little cleanup.
Add Aggregate Statistics
adds all columns for each of our different columns.
The first step is we're going to delete some of these
just to clean it up
and we'll get rid of this all at the end.
In order to get the columns back together, we again have to drag the sum up above
and the N and percent are now back in one column.
We can also right-click on the group N and remove column label
and right-click on the sum
and we're just going to change the item label to be missing
so that it's a little cleaner.
One final thing.
You'll notice that these ends
are a little bit bigger than what was on the report.
The reason for that is automatically
the top grouping variable is a sum of all of the rows underneath it.
This is not what we want for this report
because these categories are not mutually exclusive.
A subject could have both a vasoconstriction event
and a hypertension event.
But we don't want to count them twice under vascular disorders.
We only want to count them once.
In order to do that,
we're going to grab the unique subject identifier
and drag it into the ID.
Now you'll see those numbers reduced quite a bit.
Now they represent a unique subject count
for that type of event.
One other thing to point out on this report
is that we do on this data table
have a reference by unique subject identifier to TADSL.
What that means is that the table is being virtually linked
to this TADSL table,
which allows us to filter on demographic variables
that are found in the ADSL table.
Now I'm going to hand it over to Sam so he can talk about the risk reports
and how we use virtual joins to filter those tables.
Thanks, Rebecca.
That was a really nice description of that report
and how it was put together.
I'm going to show you another report
that Rebecca is responsible for developing.
This one is our adverse event risk report.
What this report will do
is it will go through all of the reported adverse events,
and it will count the number of events by treatment group
and calculate a percent or a rate.
It displays on the graph two things.
It displays two different graphs.
On the left-hand side,
it shows the rates for each treatment group.
You can see that the color key there
shows which treatment group is being displayed there.
For pruritus,
we've got a rate of pruritus in the placebo group of 9.3%.
We have a rate of pruritus in the low-dose group of 27.381%,
and in the high-dose group of 30.92%.
Usually, what we're interested in in this case
is the difference in the rates compared to the placebo group.
What's shown on the right-hand side of the graph
is the calculation of the differences for each treatment group
and the placebo group.
There are three treatment groups, so there are two computed differences:
the high dose and the low dose compared to placebo.
We also display a confidence interval around those points.
We make this report filterable.
One thing we can do is,
let's say we only want to look at
adverse events that occur at a certain rate,
maybe higher than 5% of the time,
and we can narrow that down quite a bit and reduce it.
We also have a corresponding tabulate table
that's very similar to the tabulate that Rebecca showed earlier.
What I want to do is show you how to recreate this Graph Builder graph
because there's lots of interesting things you can do in Graph Builder
that you might not be aware of.
The first thing I'm going to do is
I'm going to open up the data tables that we use,
and we actually use three different data tables.
Let me clear this report filter selection first.
There we go.
Now I'm going to open up the data tables that we use.
The first one is the data that's u sed to actually make the plot.
We call that the risk plot table.
The second table is the term ID table,
and it's just the list of unique terms
that we want to display in the graph on the Y-axis.
Then the last table is a filter table.
It's what we use to actually filter the report.
I've got all those three open.
Let's start out by making the graph of the risks and the risk differences.
I've got a Graph Builder.
We're going to take the dictionary-derived term,
drag that onto the Y-axis.
Make this bigger.
Then we're going to take the calculation,
in this case, the variable we just labeled percent,
and we're going to put that onto the X-axis.
Then what we want to do is we want to overlay by the active treatment.
Just want to put that on there.
The next thing we want to do is we want to introduce
a little bit of customization of the way the points are presented.
You can see the points,
there's a bar here where you can control the points
and the way they're drawn.
One thing is we want to make sure that they have some jitter in them.
In this case, the jitter is set to auto,
but we can set that type of jitter that we want.
I'm going to change it to center grid.
Another thing that we want to do
is we want to change the way the points are drawn.
Under the Graph menu
that you can access through right-clicking in the graph,
I'm going to right-click, Select Graph, and go to Marker Drawing mode,
and I'm going to choose outlined.
That changes those points to have an outline, a more sharp outline,
and it really makes them stand out much more significantly.
That's this plot of the percent or the rates
of each of those adverse events.
One thing I'm also going to do
is I'm just going to add a grid line o n the Y-axis,
which you can just look across then
so you can see where the individual points line up
and match that to the grouping level for the dictionary-d erived term.
That's for the rates.
The next thing I want to do is I want to look at the differences.
We have a risk difference variable and I'm going to drag that
and I'm going to drag that down onto the X-axis but to the right.
What it actually does is it creates another graph.
Now I have a graph of the risk differences.
I also want to put an interval around those.
What we do is we have two variables
that have the upper and lower limit for the intervals.
I'm going to select those and drag them to the interval zone.
You notice what happens when I do that.
It actually draws intervals around all the points on all the graphs
that I've added in here.
I don't want that on the points for the percent variable.
For the interval style or the error interval,
I'm going to set that to be none.
It turns those off.
Essentially what we've done is we've recreated the graph.
This is a little busy because there's lots of categories here.
We could just filter this table.
We could go here and we could select the local data filter.
Let's say we wanted to just filter on risk difference.
We could say,
let's only look when the risk difference may be greater than 3% in absolute value.
What I'm going to do is I'm going to set a limit
that it's between three and three and then invert that.
Then that reduces the number.
Maybe I want that to be a little bit more restrictive,
so make that 5, - 5 .
There we go.
That reduces the number that are selected.
But the thing is, it's kind of weird.
It only filtered the values for the risk difference
and it didn't filter the values for the percent.
It didn't filter everything the way we wanted it to.
We needed to do something a little bit different.
I'm going to clear that.
What I'm going to do is
I'm going to link this table, the left-hand table,
which is used to make the graph,
to the table of all of the unique levels that are displayed on the Y-axis,
all of the dictionary-derived terms.
The way we do that first is for the dictionary-derived term,
we have to make sure that the link ID property is set.
What that tells JMP is that if I link to this table,
this is the variable that I'm going to use
for matching to the table that I'm linking it to.
I set that to be the link ID.
Then over here for the dictionary-derived term,
what I need to do is I need to choose the link reference,
and I'm going to choose the actual table, this actual table as the link reference.
Now what's happened is these two tables are linked.
The last thing I need to do to specify this virtual linking properly
is to right-click, select Column Info,
and under the link reference property,
choose the row states that I want to broadcast
from the middle table to this linked table.
I want to accept the row states from the reference table.
I'm going to choose the selected, excluded, and hidden row states
and accept those from this center table.
Then when I do that, when I select rows in this data table,
I end up selecting rows in the corresponding link table.
If I hide and exclude those rows,
they become hidden and excluded in this plot
because I've hidden and excluded several of the rows in this linked table.
That's one level of linking.
But what we really want to do is we want to filter this graph
based on corresponding measures or metrics that are calculated in this table.
These are based on the differences and the risks
and other difference measures
between the placebo group and the treatment group.
What I'm needing to do to make that happen
is I need to link this right-hand table to the center table.
I'm going to do that as well.
I'm going to go here to the dictionary-d erived term
for the right-hand table,
and I'm going to choose the link reference
and pick that table that I want to link to,
which is this one displayed here.
Open up the column properties here, go to the link reference property.
Now what I want to do is I want to dispatch row states,
the selected, excluded, and hidden row states,
from this table to the linked table.
What I've done now is I've linked two tables together.
I have the table on the left is linked to the center table,
and there's a many-to-one relationship.
There's actually a three-to-one relationship.
For every row in the center table,
there are three rows in the left-hand table.
I've also linked the table on the left, which has a two-to-one relationship
where every row in the center table,
there are two rows in the right-hand table.
What I want to do is I want to push row states
from the right-hand table to the far left-hand table,
and having this linking between the two
and pushing row states from the right-hand table
to the center table,
and then those row states being accepted by the left-hand table
allows me to do that.
Now what I can do is I can filter on this table,
and I'll just open up the data filter,
and I'm going to choose the absolute risk difference.
I'm going to say if the absolute risk difference is large,
that those are the points that I want to display.
Now that I have everything linked up,
I can use the table that's on the left-hand side to filter the graph,
which is based on the data on the right-hand side.
If I go and open up a local data filter,
I'm going to turn on show and include as the options.
I'm going to choose absolute risk difference
because that's a good filtering criteria
just to find things that have a large absolute risk difference.
Then now notice it's filtering the table.
I'm filtering the left-hand table, pushing it through to the middle table,
which is pushing those row states through to the right-hand table.
Some clever virtual joins.
One thing we do in addition to JMP Clinical
is we use a callback function when we use our filters.
Actually, there's a way with JMP scripting
you can write a little function that will run
every time you change a data filter
and it can do some additional things
to customize the graph just a little bit more.
If you see it in our product, it does it a little bit differently,
but it looks pretty much the same as what I'm doing here.
Now, Rebecca can show you something.
One of our other most commonly used reports
is our findings time trends.
When you launch findings time trends, you'll get two graphs,
but I'm just going to focus on the first graph.
The first graph shows the mean change from baseline
for a given lab test over the course of the study,
shown by visits.
The bottom graph shows
the number of records at each visit for that lab test.
If we want to recreate this table, we can pop out our data table.
Again, we'll go to Graph and Graph Builder.
We're going to use Billy Rubin as an example.
We'll grab the Billy Rubin record and put it on our Y-axis.
We want our graph plotted by visit.
We'll grab visit and put it on the X-axis.
By default, we end up with points,
but we want to switch it over to a line graph.
Once we have our line graph,
we also want to split it out by treatment group.
Treatment group is not actually a variable in our base data set,
but it is a variable in the linked data set to TADSL.
We can go into our reference data set
and actually grab that plan treatment value
from the virtually joined one
and drag it over to our overlay.
That splits out our lines into two different treatment groups.
We also want to add intervals.
Under error interval,
instead of using auto, we'll change that to confidence interval.
Now we have a confidence interval for each of our visits
for each of our treatment groups.
We also want to add the bar graph.
We're going to grab Billy Rubin again
and this time drag it over into the bottom c orner of the Y-axis
so that we now have two separate panels.
By default,
we end up with just a duplicate of the panel we already created.
We're going to change this by right- clicking,
going to the line and change to bar.
Now we have a bar graph.
We can go ahead and remove our confidence intervals from this one
by selecting none under error interval.
We get pretty close to our final results with just these two panels.
But we also want to add points onto our top panel.
By default, we get a point for every single row in the data table.
We're going to just go over here and change our summary statistic to mean.
Now we're just going to clean up a little bit.
We can change the labels by clicking on the label
and then typing in a new one, so number of records.
On the top, we'll do the same thing
and change it to mean change from baseline.
We can also clean up our legend a little bit.
You'll see, because we have two panels
it actually show the treatment group twice,
we don't really want to see that.
We can go to the red triangle, go to Legend Settings,
and we'll just unclick a couple of these
so that we only see the treatment groups once.
We're back to our panel that we created in the report
and we can add our column switcher.
If you go to the red triangle and go to Redo Column Switcher,
we can change out the Billy Rubin record.
We want to change the lab test that's being shown on the Y-axis.
This dataset has a bunch of different lab tests
from alkaline phosphatase
all the way down to partial pressure oxygen.
We're just going to select all those lab tests and click OK.
Now we have a column switcher
and you can actually select each lab test
and you'll see that the graph changes to show you the lab test that's selected.
Now I'm going to hand it back to Sam
so that he can show some more complicated graphing
using patient profiles.
Thanks, Rebecca.
Just to wrap up here,
I want to show you a more advanced collection of graphs that we use
called our patient profile.
This is a way just to visualize everything that happens to a subject
in a clinical trial that's been recorded in the data.
We collect things like when did they do their study visits
and what day did that happen and what study day?
What were the disposition events that they had, the exposure they had?
Did they have adverse events
and what was the duration of the adverse events?
When did they take medications during the trial?
Vital signs that were recorded
or test results that were recorded can also be displayed.
We have a lot of ability to customize this and configure it.
This is all scripted, so I can't really show you,
"How would I build all this just with the graphical user interface and JMP?"
You need to know a little bit of JMP scripting.
But in reality,
each one of these graphs is just a graph builder
that have been put together on top of each other
and then a little bit of editing of the report layer
to remove some of the controls.
That's really what's happened.
We've also added some custom, like the legend here is a custom graphic
that we add in to display,
and it's just an image that displays in the report window.
But really, all of this is just Graph Builder for the most part.
We can switch between patients here
and look at the profile of each different patient in the trial
as we would want to.
I hope you've been able to see during this presentation
just some of the ways you can use Graph Builder and Tabulate
to summarize your data.
More than just the standard,
I did a few clicks and this is the result I get.
With a little bit of extra knowledge of how to customize the output
for the graphs and the tables that you have displayed,
you can actually get some very nice-looking output
that you can use for presentation within JMP
and even for reporting.
Some of this that we've used has been driven by regulatory guidelines
that say they would like to see tables and graphs look this way.
We've been able to achieve that using some of these features
like stacking and packing columns, and tabulate,
having multipanel displays,
doing the filtering in a unique way, and using column- switching,
to make it not just a reporting tool, but an interactive tool as well.
Thanks for your attention,
and we are happy to hear any feedback you've got
or questions about the product
or about what we've shown you in this presentation.