A Shiny app of the six bio.viz charts, one drawn at a time and chosen from
a row of pills in the page's header, on the tables it is given or, given
none, on the synthetic study that ships with the package. The R session
behind the page answers every statistic a chart asks for
(Serve_Statistics()), so a reader who changes a test, a group or a filter
gets R's result for that view, and the line under the chart says it was
computed on this server and by which R.
Usage
RunApp(
dfResults = NULL,
dfParticipants = NULL,
dfOutcomes = NULL,
lSettings = list(),
nMaxUploadMB = 100
)Arguments
- dfResults
data.frameThe results table, orNULLfor the synthetic study.- dfParticipants
data.frameThe participants table, orNULLfor none.- dfOutcomes
data.frameThe outcomes table, orNULLfor none.- lSettings
listSettings for the charts, a list for each under its chart's name:GroupComparison,AssociationScatter,CorrelationMatrix,BiomarkerScreen,CrossTaborStratifiedSurvival. Each is what that chart's widget takes aslSettings, under bio.viz's setting names. A chart not named opens on its defaults.- nMaxUploadMB
numericThe largest file the app accepts from a reader, in megabytes. Shiny's own limit is 5.
Details
The charts are the package's widgets with the controls they have. Shiny holds the tables and answers the statistics, and does nothing else: no control of a chart is made again as a Shiny input. The Data page's own controls are Shiny inputs: the three files, a select for each column of a chosen file, the control that takes a file away, and the button.
The page
A header band carries the app's name, "Biomarker charts", with the mark gsm.bio and its version beside it; a row of pills, Data first and then the six charts; and a chip that says what the charts are drawn on, on every page, and opens Data when it is pressed. The chart has the page's width under the band, and one footer line says which R computes the statistics and that a reader's files are held for the session only.
A pill is a link of Shiny's own tab set. A keyboard reaches the chosen pill with the Tab key and walks the row with the arrow keys, and a pill pointed at says in one line what its chart draws.
A chart that cannot be drawn on the tables there are has its pill dimmed, with the reason as its hover text. The pill still opens the chart's page, which holds the same sentence.
On a phone the header is two rows and the pills scroll sideways in their own row, with the chosen one brought into view.
The page asks Google Fonts for the two fonts bio.viz's and safety.viz's sites use, Instrument Sans and Instrument Serif, and for nothing else outside its own server. It does not wait for them: where they cannot be reached, as behind a firewall, the page is drawn in the system's fonts.
The tables
The app reads its tables under gsm.bio's column names, so a table with other names is renamed before the call:
results, needed:
USUBJID,TEST,STRESN,VISITandVISITNUM, one row per participant, biomarker and visit;participants, optional:
USUBJIDand whatever columns describe a participant. With it a chart offers groups and filters; without it a chart has none;outcomes, optional:
USUBJID,PARAMCD,PARAM,AVALandCNSR. Without it the stratified survival chart is replaced by a sentence saying so, and its pill is dimmed.
A table that lacks a column is refused with a sentence naming the column. Called with no table, the app opens on Synthetic_Results, Synthetic_Participants and Synthetic_Outcomes.
A reader's own files
The first pill opens the Data page. It has a card for each table: results,
which the charts need, and participants and outcomes, which are optional.
A reader chooses a file in a card, each a .csv, .xpt or .sas7bdat
file, and R reads it on the server. The card then asks which of the file's
columns is each one the charts need. A column that has gsm.bio's own name
is filled in already and tagged "same name"; one the reader has still to
say is amber and tagged "say which". On the button the columns are renamed
to gsm.bio's names and the charts are drawn on the reader's tables, and the
page lists the charts that are ready, each with what it draws. Each opens
from that list, and a chart that lacks a table says which.
A rail beside the cards, above them on a phone, counts what is left in three steps: the files chosen and any R could not read, the columns still to say, and the charts that are ready. Under the steps it says what the charts are drawn on now.
Nothing is drawn on a table until every column is said: a column left
unsaid, a column chosen twice, a result that is text and a file R cannot
read are each answered with a sentence beside the button, and the tables
already drawn stay. A file R cannot read is also reported in the card it
was chosen in. A column of the file that already had one of gsm.bio's
names, and was not the one chosen for it, is kept with _original added to
its name.
A file is taken away with the Remove control in its card. Until it is, it is one of the files the button draws: the page names them all beside the button, so a file chosen for an earlier study is seen before it is drawn with a later one. An optional file R could not read holds the button until it is removed or another is chosen in its place.
The Data page also shows what is loaded: the tables the charts are drawn
on, ten rows at a time, with where each came from and its rows and columns.
A file just chosen shows its first rows under its own column names, so a
reader can tell which column is which. Values are shown as R holds them. A
number is written in full to the fifteen digits that identify it, never as
1e+05, unless it is a thousand million million or more, or smaller than
a part in that many; those are left in R's scientific form.
A file is held in the session's memory and nowhere else. Nothing is written
to the server beyond Shiny's own temporary copy of an upload, which goes
when the session ends, and nothing is kept between sessions. A .xpt or
.sas7bdat file is read with haven, which is suggested, not imported:
without it the page says so and reads .csv files only.
On a server
RunApp() returns the app and starts nothing itself, so the same call
serves an R session, where printing the app runs it, and the last line of
an app.R on a server such as Posit Connect:
The tables are held in the R session's memory. The rows a chart draws are
sent to the session with each request for a statistic, and the session runs
the nine Analyze_* functions and no other.
shiny is suggested, not imported: without it RunApp() stops with a
sentence naming the package to install.
See also
Serve_Statistics() and the output and render functions in
gsm.bio-shiny, which the app is made of.
Other shiny:
Serve_Statistics(),
gsm.bio-shiny
Examples
if (interactive() && requireNamespace("shiny", quietly = TRUE)) {
# The synthetic study.
RunApp()
# A study's own tables, with the group comparison opened on one biomarker
# by arm.
RunApp(
Synthetic_Results, Synthetic_Participants,
lSettings = list(GroupComparison = list(start_value = "CRP", group_by = "ARM"))
)
}