Compare commits

...

35 Commits

Author SHA1 Message Date
Guxa d450000178 pkgdown: some bugs fixed in function documentation
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 45s
run tests / build-and-deploy-documentation (push) Successful in 7s
2026-06-07 22:43:30 +02:00
Guxa 5071896110 plots in OPTIMIZE improved
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 47s
run tests / build-and-deploy-documentation (push) Successful in 8s
2026-06-07 22:35:43 +02:00
Guxa abf02ef4ec Dilution simulator updated
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 47s
run tests / build-and-deploy-documentation (push) Successful in 8s
2026-06-05 11:32:15 +02:00
Guxa f5575f8429 merge conflict resolved app.R updated
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 46s
run tests / build-and-deploy-documentation (push) Successful in 8s
2026-06-04 10:46:38 +02:00
Simon Innerbichler 058027f721 Documentation runs @examples code correctly.
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 45s
run tests / build-and-deploy-documentation (push) Successful in 7s
IMPORTANT: examples must be written in a self-contained way
They always run from a clean workspace with no global variables.
2026-06-03 11:53:57 +02:00
Simon Innerbichler b2eb61a820 Documentation runs @examples code correctly.
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 42s
run tests / build-and-deploy-documentation (push) Successful in 7s
IMPORTANT: examples must be written in a self-contained way
They always run from a clean workspace with no global variables.
2026-06-03 11:48:40 +02:00
Simon Innerbichler 4cfdc288a8 IMPORTANT added linting configuration
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 44s
run tests / build-and-deploy-documentation (push) Successful in 8s
linting can be started by clicking Addins in RStudio, then
"Lint current file". This commit also contains quick fixes for common
linter messages like changing F to FALSE and T to TRUE.
2026-06-03 10:33:40 +02:00
Guxa 4cfda9d162 rport updates, new logo, app.r logic updated, 4pl XL made nicer
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 44s
run tests / build-and-deploy-documentation (push) Successful in 7s
2026-06-02 15:43:15 +02:00
Guxa c480111552 report generation after new setup of repo; linearity XL report improved
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 48s
run tests / build-and-deploy-documentation (push) Successful in 9s
2026-06-01 19:35:36 +02:00
Simon Innerbichler cf1ce314e1 moved TestFileRoxygen.R to scripts/
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 42s
run tests / build-and-deploy-documentation (push) Successful in 7s
2026-05-25 10:11:02 +02:00
Simon Innerbichler 3afd241dfc added automatic testing on push to main
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 46s
run tests / build-and-deploy-documentation (push) Failing after 4s
2026-05-25 09:44:09 +02:00
Simon Innerbichler c14e919a18 removed dependency management from documentation build
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 51s
2026-05-25 09:39:18 +02:00
Simon Innerbichler 12eabc4d0c added thestthat
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Failing after 7s
test files in tests/testthat/
2026-05-25 09:36:45 +02:00
Guxa e71cfd1b6a rtf to txt, bugfix
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 55s
2026-05-24 17:59:47 +02:00
Simon Innerbichler 69e3545ac7 extraneous library call
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Successful in 48s
2026-05-19 14:28:17 +02:00
Simon Innerbichler 5254900810 added automatic building+deploy of docs
Build and deploy Roxygen2|pkgdown documentation site / build-and-deploy-documentation (push) Failing after 1m5s
2026-05-19 14:22:15 +02:00
Simon Innerbichler 8106bed956 _pkgdown.yml for bootstrap 5 2026-05-19 14:17:59 +02:00
Simon Innerbichler d44c88eef7 added dependencies to DESCRIPTION 2026-05-19 13:12:36 +02:00
Simon Innerbichler 18433be282 pkgdown + roxygen2 working now
libraries must be called everywhere that a
function requires a member of said library.
This way, files can be loaded independently of
eacho other, which is important.
2026-05-19 11:52:40 +02:00
Simon Innerbichler 335dfc653d formatted app.R 2026-05-19 11:23:27 +02:00
Simon Innerbichler 1b3af203a2 formatted Global.R 2026-05-19 11:21:39 +02:00
Simon Innerbichler a69a7db1b7 fixed DESCRIPTION 2026-05-19 09:25:19 +02:00
Simon Innerbichler b5bad4ed0f readded reactiveValues declarations 2026-05-19 08:58:43 +02:00
Simon Innerbichler 18661b8d0c restructuring 2026-05-19 08:31:07 +02:00
Simon Innerbichler 7a75b53b5b fixed source Global.R path 2026-05-19 08:12:31 +02:00
Guxa b0cf97a5ee Global.R into dev 2026-05-18 17:40:35 +02:00
Guxa b38e60e1a3 new structure acc. to golem 2026-05-18 17:32:38 +02:00
Simon Innerbichler 57a726ed27 added DESCRIPTION and Rproj 2026-05-18 08:43:56 +02:00
Guxa 420c78d4c4 example XLs files added to www, test files 'circles.xlsx' and 'all_l.xlsx'added. 2026-05-17 16:24:22 +02:00
Guxa 9ff1a360d4 Catch singularities when fitting 4pl, SCRUM jobs listed 2026-05-17 11:13:02 +02:00
Guxa ec13d95387 cleanup and bugfix; linearity report made work 2026-05-15 22:11:20 +02:00
Guxa 9422490f25 4PL report update 2026-05-14 18:38:27 +02:00
Guxa 9861af5fba Report for linear PLA added; Roxygen RMD file added which serves also as testing file
bug fixes in the code; Code made flexible regarding EXCEL upload and metadata evaluation.
Functions now in "Global.R" file
2026-05-14 10:42:33 +02:00
Guxa 1555fe3b6c app made independent XL and metadata, functions roxygenized 2026-05-13 15:08:12 +02:00
Guxa a4bdbe8f8c roxygenized the function documentation 2026-05-12 22:43:06 +02:00
121 changed files with 9921 additions and 432 deletions
Vendored
BIN
View File
Binary file not shown.
@@ -0,0 +1,4 @@
assistant="default"
chat_provider="default"
copilot_enabled="-1"
copilot_indexing_enabled="-1"
@@ -0,0 +1,7 @@
auto_roxygenize_for_build_and_reload="1"
auto_roxygenize_for_build_package="1"
auto_roxygenize_for_check="1"
live_preview_website="0"
makefile_args=""
preview_website="1"
website_output_format="all"
@@ -0,0 +1,9 @@
{
"sortOrder": [
{
"columnIndex": 2,
"ascending": true
}
],
"path": "~/plateflow/NewApp"
}
@@ -0,0 +1,3 @@
{
"activeTab": 3
}
@@ -0,0 +1,14 @@
{
"left": {
"splitterpos": 349,
"topwindowstate": "NORMAL",
"panelheight": 872,
"windowheight": 910
},
"right": {
"splitterpos": 493,
"topwindowstate": "NORMAL",
"panelheight": 872,
"windowheight": 910
}
}
@@ -0,0 +1,6 @@
{
"TabSet1": 0,
"TabSet2": 1,
"TabZoom": {},
"Sidebar": 0
}
+5
View File
@@ -0,0 +1,5 @@
@@ -0,0 +1,3 @@
{
"file_monitor_use_gitignore": true
}
@@ -0,0 +1 @@
{"active_set":"","sets":[]}
@@ -0,0 +1,6 @@
{
"source_window_id": "",
"Source": "Source",
"cursorPosition": "149,33",
"scrollLine": "0"
}
@@ -0,0 +1,7 @@
{
"tempName": "Untitled1",
"source_window_id": "",
"Source": "Source",
"cursorPosition": "53,0",
"scrollLine": "32"
}
@@ -0,0 +1,8 @@
{
"source_window_id": "",
"Source": "Source",
"cursorPosition": "2726,27",
"scrollLine": "2716",
"docOutlineVisible": "1",
"docOutlineSize": "118"
}
@@ -0,0 +1,6 @@
{
"source_window_id": "",
"Source": "Source",
"cursorPosition": "43,17",
"scrollLine": "18"
}
@@ -0,0 +1,7 @@
{
"tempName": "Untitled1",
"source_window_id": "",
"Source": "Source",
"cursorPosition": "53,0",
"scrollLine": "32"
}
@@ -0,0 +1,7 @@
{
"source_window_id": "",
"Source": "Source",
"docOutlineVisible": "1",
"cursorPosition": "470,1",
"scrollLine": "456"
}
@@ -0,0 +1,6 @@
{
"source_window_id": "",
"Source": "Source",
"cursorPosition": "917,0",
"scrollLine": "911"
}
@@ -0,0 +1,7 @@
~%2Fplateflow%2FNewApp%2Fapp.R="2E42830B"
~%2Fplateflow%2Fwizard%2Fserver.R="D28532A3"
~%2Fplateflow%2Fwizard%2Fui.R="0498AE4A"
~%2Fplateflow%2FwizardNew%2FDataGenerator.R="75D6CC68"
~%2Fplateflow%2FwizardNew%2FUntitled.R="1F7C96C9"
~%2Fplateflow%2FwizardNew%2Fserver.R="E0EFE663"
~%2Fplateflow%2FwizardNew%2Fui.R="690ECC06"
@@ -0,0 +1,26 @@
{
"id": "00336B5B",
"path": "~/plateflow/wizard/ui.R",
"project_path": null,
"type": "r_source",
"hash": "0",
"contents": "",
"dirty": false,
"created": 1777315188063.0,
"source_on_save": false,
"relative_order": 3,
"properties": {
"source_window_id": "",
"Source": "Source",
"cursorPosition": "149,33",
"scrollLine": "0"
},
"folds": "",
"lastKnownWriteTime": 1776610618,
"encoding": "UTF-8",
"collab_server": "",
"source_window": "",
"last_content_update": 1776610618,
"read_only": false,
"read_only_alternatives": []
}
@@ -0,0 +1,277 @@
library(shiny)
library(shinyjs)
library(shinyAce)
library(bslib)
version <- "1.0.0"
function(req) {
fluidPage(
useShinyjs(),
titlePanel("Dilution Wizard"),
tags$head(tags$style((".shiny-notification {position: fixed; top: 20%;left: 50%; margin-top: -100px;
margin-left: -250px; color: blue;font-size: 20px; font-style: italic;}")),
tabsetPanel(id="toptab",
tabPanel("Data entry",
wellPanel(
fluidRow(
tags$head(tags$style(HTML("label {font-size:80%;margin-bottom: 3px;margin-top: 3px;}"))),
column(2,
tags$image(src="logo.png", class="adv_logo"),
h4("upload EXCEL"),
fileInput(inputId = "iFile", label = "", accept="ms-excel"),
uiOutput(outputId = "sheetName"),
div(checkboxInput("PureErr", "Should pure error be used for calculation of CIs?", FALSE),
style = "font-size: 24px !important;color: red"),
verbatimTextOutput("stats"),
h5("\n\n\n Author: Franz Innerbichler, InnerAnalytics")),
div(id="parameter",
column(1,style = "background: lightgrey",
#actionButton("StartCalc", "Click, when calculations to be started"),
h4("curve settings"),
numericInput("lowAsymptREF", "lower asymptote REF",10,step=1,min=0),
numericInput("lowAsymptTEST", "lower asymptote TEST",10,step=1,min=0),
numericInput("uppAsymptREF", "upper asymptote REF",110,step=1,min=0),
numericInput("uppAsymptTEST", "upper asymptote TEST",110,step=1,min=0)
),
column(1,style = "background: lightgrey",
numericInput("slopeREF", "slope REF",1,step=0.1,min=-10),
numericInput("slopeTEST", "slope TEST",1,step=0.1,min=-10),
numericInput("EC50", "EC50 REF",-3.5),
numericInput("potDiff", "potency difference",0)
),
column(1,style = "background: lightgreen",
h4("dilutions"),
numericInput("CONC1", "highest concentration",0.3, min=-3.5),
numericInput("CONC2", "2nd concentration",0.15),
numericInput("CONC3", "3rd concentration",0.075),
numericInput("CONC4", "4th concentration",0.0375),
numericInput("CONC5", "5th concentration",0.01875),
numericInput("CONC6", "6th concentration",0.00938)
),
column(1,style = "background: lightgreen",
numericInput("CONC7", "7th concentration",0.00469),
numericInput("CONC8", "8thd concentration",0.00235),
numericInput("CONC9", "9thd concentration",NA),
numericInput("CONC10", "10th concentration",NA),
numericInput("CONC11", "11th concentration",NA),
numericInput("CONC12", "lowest concentration",NA)
),
column(1,style = "background: lightblue",
h4("geometric dilution scheme"),
numericInput("ConcStart", "starting concentration",NA),
numericInput("dilutionFac", "dilution factor",NA),
numericInput("NoDil", "no. of dilutions",NA),
numericInput("NoDilSer", "no. of dil. series",NA),
verbatimTextOutput("dilutions")
),
column(4,
h4("log-dilution scheme"),
verbatimTextOutput("logdil"),
h4("User help"),
h5("If new dilutions are entered, please adjust EC50 to avoid calculation errors"))
)
)
)),
#### XLSX diagnostics ----
tabPanel ("XLSX diagnostics",
tags$style(HTML("pre { color: black; background-color: #FFE1FF;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size: 12px;} ")),
wellPanel(
fluidRow(
column(2,
h5("Diagnostics only shown if EXCEL is uploaded"),
htmlOutput("PureErrW2"),
tags$head(tags$style("#PureErrW2{color: red;
font-size: 16px;
font_style: italic;}")),
tableOutput("FileSAmpl"),
downloadButton("downloadXLReport", label="Download PDF report", class="butt"),
tags$style(type="text/css","#downloadXLReport {background-color: orange; color: black;font-family: COurier New}"),
plotOutput("relpotTestPlot", width="300px", height="150px"),
h4("Akaike Information Criterion"),
tableOutput("AIC"),
h5("First row: restricted model; 2nd row: unrestricted model"),
h5("Smaller values of AIC indicate better fit to the data"),
tableOutput("VarDiagn")
),
column(4,
plotOutput("XLplot"),
column(6,
br(),
"Regression results restricted",
tableOutput("coeffs_r"),
"Bend points restricted",
tableOutput("coeffs_r2")),
column(6,
br(),
"Regression results unrestricted",
tableOutput("coeffs_unr"))),
column(4,
plotOutput("diagnplot"),
column(6,
tableOutput("logcoeffs_r"),
tableOutput("coeffs_unr2")),
column(6,
tableOutput("logcoeffs_unr"))),
column(2,
tableOutput("ANOVAXLS"),
DT::renderDataTable("EQtests"))
)
)),
#### 4pl fits ----
tabPanel("4pl-fit",
wellPanel(
fluidRow(
column(6,
tags$style(span(htmlOutput("PureErrW3"), style="color: red")),
htmlOutput("PureErrW3"),
tags$head(tags$style("#PureErrW2{color: red;
font-size: 16px;
font_style: italic;}")),
plotOutput("plot"),
DT::dataTableOutput("pottab4pl"),
"Footnote: test performed on absolute CIs."),
column(6,
DT::dataTableOutput("secondary"), # SSTs
h5("*...The estimate for F-test on regression and on non-linearity is the p-value"),
h5("F-test on regression passes if F-value > F-crit and thus p < 0.05"),
h5("F-test on non-linearity passes if F-value < F-crit and thus p > 0.05"),
h5("Test results outcome: 0 ... test passed (for EQ tests: CI within limits);
1 ... test failed (for EQ tests CI not within limits);
-1 ... calculations unbound/denominator too close to 0"),
#plotOutput("CIplot, height=50%")
)
))
),
#### Linear PLA ----
tabPanel("Linear PLA",
wellPanel(
fluidRow(
column(6,
htmlOutput("PureErrW3"),
tags$head(tags$style("#PureErrW2{color: red;
font-size: 16px;
font_style: italic;}")),
plotOutput("plotLin"),
"Delta method is used for potency CIs",
DT::dataTableOutput("pottab"),
h4("Unrestricted linear model (SSSI):"),
tableOutput("SummaryModABu"),
h4("Restricted linear model (CSSI):"),
tableOutput("SummaryModAB")),
column(3,
h3("Tests for linear PLA):"),
DT::dataTableOutput("TESTSlin"),
h5("The estimate is the p-value of the test"),
h5("F-tests on regression, significance of slopes, and preparation need to have a p-value <0.05 to pass"),
h5("All other tests pass if p-value > 0.05"),
"SST CI for difference of slopes:",
tableOutput("SlopeDiffCI")),
column(3,
h3("ANOVA for parallel line assay"),
DT::dataTableOutput("ANOVAlin"))
)
)),
#### Dilution simulator ----
tabPanel("Dilution simulator",
wellPanel(
fluidRow(
column(4,
h3("Confidence intervals"),
tableOutput("CIs"),
"The confidence intrval table is interaactive for changes in: variability slider (%SD), potency of test-slider,
and 'Adjust the dilutions'-slider",
tableOutput("optimalDils"),
selectInput(inputId="scenario", label= "Select an 'optimal' scenario:", choices = c("scenario 2","scenario 3","scenario 6","steep slope"))),
column(5,
plotOutput("plotfordilutions"),
h4("in grey: most extreme bend point lines of theoretical samples with 50% and 200% potency"),
sliderInput("dilslider", "Adjust the dilutions(+-change in %)", min = -100,max=100, value=0, step=1, round=0),
checkboxInput("fixupper","Fix highest concentration (if unticked, the center is fixed)",FALSE),
h5("Dilution factors"),
tableOutput("adjlogdil"),
"Short guidance: wider dilution ranges increase the CIs of rel. potency, and decrease the CIs of upper and lower asymptote ratios, as well as Hill's slope ratios", br(),
"Narrower dilution ranges decrease the CIs of rel. potency, and increase the CIs of upper and lower asymptote ratios, ands Hill's slope ratios",),
column(3,
h3("Bend points"),
tableOutput("bps"),
tableOutput("extremebps"),
h4("Explanation of the plots")
)
)
)),
#### EQ limits simulation ----
tabPanel("EQ-limit simulatioin",
wellPanel(
fluidRow(
column(1, style="background: lightblue",
numericInput("simN","number of datasets to simulate", 100, step=10, min=10, max=1000),
numericInput("lowQuant", "lower quantile", 1, min = 0.01,max=20),
numericInput("uppQuant", "upper quantile", 99, min = 801,max=99.99),
actionButton('goSim', "Start simulation",class="btn-success")
),
column(4,
h4("estimation of EACs for slope ratio, dynamic range-ratio, upper asymptote ratio, and potency"),
plotOutput("plotHistuAs", width = "1400px", height = "400px"))
)
)),
#### Documentation ----
tabPanel("Documentation",
h4("Information on dilution setting"),
"(for details see:", a(href="ADONIS.pdf","Whitepaper", download=NA, target="_blank"),")",tags$br(),
"Bend points are calculated according to following formula:",
withMathJax(" $$bp_{1/2} = \\pm\\frac{1.31696}{Hill's slope}$$"))),
#### setting lower panel ----
wellPanel(
fluidRow(
column(2,
h3("Settings"),
helpText("Vary the slider to see the effect of special cause"),
sliderInput("sdfac","Variability as % of lower to upper asymptote", max=10, value=3, min=0.1, step=0.1),
checkboxInput("heterosked","heteroskedastic noise", FALSE),
sliderInput("potencydiff","potency of test (%)", max=200, min=50, value=100, step=1),
sliderInput("outlL","outlier in lower asymptote", min=0, max=1.5, value=0, step=0.1),
sliderInput("outlM","outlier in mid part", min=0, max=1.5,value=0, step=0.1),
sliderInput("outlU","outlier in upper asymptote", min=0, max=1.5,value=0, step=0.1)
),
column(1,
tags$table(id="dose-table",
numericInput("lEACdiffla","lower EAC for diff. of LA", -0.175, step=0.001),
numericInput("uEACdiffla","upper EAC for diff. of LA", 0.189, step=0.001),
numericInput("lEACratiola","lower EAC ratio of LAs", 0.005, step=0.001),
numericInput("uEACratiola","upper EAC for ratio of LAs", 100, step=1),
numericInput("lEACratioSlope","lower EAC for ratio of slopes", 0.55, step=0.01),
numericInput("uEACratioSlope","upper EAC for ratio of slopes", 1.84, step=0.1),
numericInput("lEACratioua","lower EAC for ratio of UAs", 0.75, step=0.1),
numericInput("uEACratioua","upper EAC for ratio of UAs", 1.33, step=0.1),
numericInput("lowerPot","lower EAC for potency", 75, step=1),
numericInput("upperPot","upper EAC for potency", 133, step=1),
numericInput("lEACratioAdiff","lower EAC of ratio of asymptote differences", 0.75, step=0.01),
numericInput("uEACratioAdiff","upper EAC of ratio of asymptote differences", 1.33, step=0.01)
)),
column(4,
"4 PL ANOVA unrestricted",
DT::dataTableOutput("ANOVA"),
h5("Please note that for the CIs of rel. potency the RSS of the restricted model is used"),
h5("RSS ... 'Residual error' in the SumSquares column"),
h5("MSE ... 'Residual error' in the MSs column"),
h5("SSE ... 'Pure error' in the SumSquares column"),
h5("RMSE ... Square root of the 'Residual Error' in the MS column"),
verbatimTextOutput("RMSE")
),
column(5,
DT::dataTableOutput("Conctab"))
)
)
)
)
}
@@ -0,0 +1,27 @@
{
"id": "2D702BEF",
"path": "~/plateflow/wizard/server.R",
"project_path": null,
"type": "r_source",
"hash": "0",
"contents": "",
"dirty": false,
"created": 1777235022084.0,
"source_on_save": false,
"relative_order": 2,
"properties": {
"source_window_id": "",
"Source": "Source",
"docOutlineVisible": "1",
"cursorPosition": "470,1",
"scrollLine": "456"
},
"folds": "",
"lastKnownWriteTime": 1777235902,
"encoding": "UTF-8",
"collab_server": "",
"source_window": "",
"last_content_update": 1777235902359,
"read_only": false,
"read_only_alternatives": []
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
{
"id": "3F7244B6",
"path": null,
"project_path": null,
"type": "r_dataframe",
"hash": "0",
"contents": "",
"dirty": false,
"created": 1778393027500.0,
"source_on_save": false,
"relative_order": 6,
"properties": {
"expression": "slopeSt",
"caption": "slopeSt",
"totalObservations": "10",
"displayedObservations": "10",
"variables": "2",
"cacheKey": "B95B358D",
"object": "slopeSt",
"environment": "_rs_no_env",
"contentUrl": "grid_resource/gridviewer.html?env=_rs_no_env&obj=slopeSt&cache_key=B95B358D&max_display_columns=50",
"preview": "0",
"source_window_id": "",
"Source": "Source"
},
"folds": "",
"lastKnownWriteTime": 0,
"encoding": "",
"collab_server": "",
"source_window": "",
"last_content_update": 1778393027500,
"read_only": false,
"read_only_alternatives": []
}
@@ -0,0 +1,28 @@
{
"id": "47543094",
"path": "~/plateflow/NewApp/app.R",
"project_path": "app.R",
"type": "r_source",
"hash": "1413864872",
"contents": "",
"dirty": false,
"created": 1777232335294.0,
"source_on_save": false,
"relative_order": 3,
"properties": {
"source_window_id": "",
"Source": "Source",
"cursorPosition": "2726,27",
"scrollLine": "2716",
"docOutlineVisible": "1",
"docOutlineSize": "118"
},
"folds": "",
"lastKnownWriteTime": 1778405820,
"encoding": "UTF-8",
"collab_server": "",
"source_window": "",
"last_content_update": 1778405820161,
"read_only": false,
"read_only_alternatives": []
}
@@ -0,0 +1,34 @@
{
"id": "909E8FCF",
"path": null,
"project_path": null,
"type": "r_dataframe",
"hash": "0",
"contents": "",
"dirty": false,
"created": 1778393048148.0,
"source_on_save": false,
"relative_order": 7,
"properties": {
"expression": "pl_df",
"caption": "pl_df",
"totalObservations": 11,
"displayedObservations": 11,
"variables": 3,
"cacheKey": "5D429755",
"object": "pl_df",
"environment": "_rs_no_env",
"contentUrl": "grid_resource/gridviewer.html?env=_rs_no_env&obj=pl_df&cache_key=5D429755&max_display_columns=50",
"preview": 0,
"source_window_id": "",
"Source": "Source"
},
"folds": "",
"lastKnownWriteTime": 0,
"encoding": "",
"collab_server": "",
"source_window": "",
"last_content_update": 1778393048148,
"read_only": false,
"read_only_alternatives": []
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
{
"id": "9E593C09",
"path": null,
"project_path": null,
"type": "r_dataframe",
"hash": "0",
"contents": "",
"dirty": false,
"created": 1778393675522.0,
"source_on_save": false,
"relative_order": 8,
"properties": {
"expression": "slopeTe",
"caption": "slopeTe",
"totalObservations": 10,
"displayedObservations": 10,
"variables": 2,
"cacheKey": "E00BF6E9",
"object": "slopeTe",
"environment": "_rs_no_env",
"contentUrl": "grid_resource/gridviewer.html?env=_rs_no_env&obj=slopeTe&cache_key=E00BF6E9&max_display_columns=50",
"preview": 0,
"source_window_id": "",
"Source": "Source"
},
"folds": "",
"lastKnownWriteTime": 0,
"encoding": "",
"collab_server": "",
"source_window": "",
"last_content_update": 1778393675522,
"read_only": false,
"read_only_alternatives": []
}
@@ -0,0 +1,51 @@
#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# https://shiny.posit.co/
#
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Old Faithful Geyser Data"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$distPlot <- renderPlot({
# generate bins based on input$bins from ui.R
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
# draw the histogram with the specified number of bins
hist(x, breaks = bins, col = 'darkgray', border = 'white',
xlab = 'Waiting time to next eruption (in mins)',
main = 'Histogram of waiting times')
})
}
# Run the application
shinyApp(ui = ui, server = server)
@@ -0,0 +1,27 @@
{
"id": "AFA288F2",
"path": "~/plateflow/wizardNew/DataGenerator.R",
"project_path": null,
"type": "r_source",
"hash": "0",
"contents": "",
"dirty": false,
"created": 1777554257099.0,
"source_on_save": false,
"relative_order": 4,
"properties": {
"tempName": "Untitled1",
"source_window_id": "",
"Source": "Source",
"cursorPosition": "53,0",
"scrollLine": "32"
},
"folds": "",
"lastKnownWriteTime": 1777557164,
"encoding": "UTF-8",
"collab_server": "",
"source_window": "",
"last_content_update": 1777557164367,
"read_only": false,
"read_only_alternatives": []
}
@@ -0,0 +1,54 @@
Calc_DilRes <- function(as=3, bs=1, cs=-4, ds=10, at=3, bt=1, dt=10,r=0.0001,ct=cs-r,
sd_fac=0.1, gt=1, gs=1, log_conc,
heteroNoise=FALSE, noDilSeries, noDils) {
yAxfac <- (ds-as)
log_dose <- log_conc
isRef <- rep(c(1,0),1,each=length(log_conc)*noDilSeries)
isSample <- rep(c(0,1),1,each=length(log_conc)*noDilSeries)
browser()
av <- as*isRef + at*isSample + (ds*isRef + dt*isSample - as*isRef - at*isSample)/
(1+isRef*exp(bs*(cs - log_dose)) + isSample*exp(bt*(ct-log_dose)))
if (heteroNoise) {
# heterosc noise
ro_jit <- matrix(unlist(map(av, function(x) x+rnorm(1,0,x*sd_fac/100))), nrow=noDils, ncol=noDilSeries*2)
} else {
# homosc noise
ro_jit <- matrix(unlist(map(av, function(x) x+rnorm(1,0,sd_fac*yAxfac/100))), nrow=noDils, ncol=noDilSeries*2)
}
ro_jit <- abs(ro_jit)
ro_jit2 <- cbind(ro_jit, log_dose)
if (noDilSeries==3) {
colnames(ro_jit2) <- c("R_dil1","R_dil2","R_dil3","T_dil1","T_dil2","T_dil3", "log_dose")
} else {
colnames(ro_jit2) <- c("R_dil1","R_dil2","T_dil1","T_dil2", "log_dose")
}
return(ro_jit2)
}
library(openxlsx)
Conc <- 9*1/(3^(1:11))
Conc_ <- c(9, Conc)
ro_new <- list()
ro_new[[1]] <- Calc_DilRes(as=1000, bs=-2, cs=-4, ds=10000, at=1000, bt=-2, dt=10000, log_conc = log(Conc_),
sd_fac=3.3,
# auslenkU=outlierU,
# auslenkM=outlierM,
# auslenkL=outlierL,
heteroNoise = F, noDilSeries = 2, noDils = 12)
ro_new[[2]] <- Calc_DilRes(as=1000, bs=-2, cs=-4, ds=10000, at=1000, bt=-2, dt=10000, log_conc = log(Conc_),
sd_fac=3.3,r=0.1,
# auslenkU=outlierU,
# auslenkM=outlierM,
# auslenkL=outlierL,
heteroNoise = F, noDilSeries = 2, noDils = 12)
ro_new[[3]] <- Calc_DilRes(as=1000, bs=-2, cs=-4, ds=10000, at=1000, bt=-2, dt=10000, log_conc = log(Conc_),
sd_fac=3.2, r=-0.3,
# auslenkU=outlierU,
# auslenkM=outlierM,
# auslenkL=outlierL,
heteroNoise = F, noDilSeries = 2, noDils = 12)
write.xlsx(ro_new, "~/plateflow/wizard/Tests3Plates.xlsx")
@@ -0,0 +1,45 @@
library(shiny)
library(shinydashboard)
library(fontawesome)
ui <- dashboardPage(
dashboardHeader("wizard"),
dashboardSidebar(
sidebarMenu(
img(src="logo.png", width=230),
menuItem("Home", tabName="home", icon=icon("home")),
menuItem("Data template", tabName = "template", icon=icon("table"),
menuSubItem( tags$li(a("EXCEL File", target="self",href="TestFIle.xlsx")))
),
menuItem("User Manual /Validation", tabName = "manual", icon=icon("book"),
menuSubItem(icon = NULL, tags$li(a("Document", target="self",href="UserManual.pdf")))
),
menuItem("EXCEL upload", tabName="Dataupload", icon=icon("magnet", lib="glyphicon")),
menuItem("4PL + report", tabName="4PL", icon=icon("chart-line", lib="font-awesome")),
menuItem("Linear regression + report", tabName="pla", icon=icon("pencil", lib="glyphicon")),
menuItem("Wizard", tabName="wizard", icon=icon("chart-column", lib="font-awesome")),
menuItem("Documentation", tabName="documentation", icon=icon("chart-area", lib="font-awesome"))
),
tags$footer(HTML(paste("Owned by",tags$strong(tags$u("InnerAnalytics")), paste(rep("&nbsp",9), collapse=""),
"Developer:", paste(rep("&nbsp",9), collapse=""),
"Host on:", paste(rep("&nbsp",9), collapse=""),
"Version:")),
align="left", style=
"position:fixed; bottom_=;;width=100%; background: #7FAEFF; font-family: Times New Roman; font-size:100%;
padding: 5px; color:#990000; box-sizing: border-box; z-index: 1000;")
),
dashboardBody(
fluidPage(
tabItems(
tabItem(tabName = "home", htmlOutput("homePage")),
tabItem(tabName = "Datapload", uiOutput("Dataupload")),
tabItem(tabName = "fourPL", uiOutput("fourPL")),
tabItem(tabName = "pla", uiOutput("pla")),
tabItem(tabName = "wizard", uiOutput("wizard"))
)
)
) , skin="blue"
)
@@ -0,0 +1,34 @@
{
"id": "FC76AEE8",
"path": null,
"project_path": null,
"type": "r_dataframe",
"hash": "0",
"contents": "",
"dirty": false,
"created": 1778097939830.0,
"source_on_save": false,
"relative_order": 5,
"properties": {
"expression": "Conctab",
"caption": "Conctab",
"totalObservations": 12,
"displayedObservations": 12,
"variables": 8,
"cacheKey": "E00A59C5",
"object": "Conctab",
"environment": "_rs_no_env",
"contentUrl": "grid_resource/gridviewer.html?env=_rs_no_env&obj=Conctab&cache_key=E00A59C5&max_display_columns=50",
"preview": 0,
"source_window_id": "",
"Source": "Source"
},
"folds": "",
"lastKnownWriteTime": 0,
"encoding": "",
"collab_server": "",
"source_window": "",
"last_content_update": 1778097939830,
"read_only": false,
"read_only_alternatives": []
}
@@ -0,0 +1,5 @@
/Users/franzinnerbichler/plateflow/NewApp/app.R="232C6386"
/Users/franzinnerbichler/plateflow/wizardNew/DataGenerator.R="038FF5B5"
/Users/franzinnerbichler/plateflow/wizardNew/Untitled.R="405C9157"
/Users/franzinnerbichler/plateflow/wizardNew/server.R="710F8608"
/Users/franzinnerbichler/plateflow/wizardNew/ui.R="CB737866"
@@ -0,0 +1,34 @@
name: Build and deploy Roxygen2|pkgdown documentation site
run-name: Documentation Build on push to main branch
on:
push:
branches:
- main
jobs:
build-and-deploy-documentation:
runs-on: linux_amd64
steps:
- name: Checkout repository
uses: actions/checkout@v4
# - name: Install package dependencies
# run: |
# Rscript -e 'remotes::install_deps(dependencies = TRUE)'
- name: Call to roxygen2::roxygenise()
run: |
Rscript -e 'roxygen2::roxygenise()'
- name: Call to pkgdown::build_site()
run: |
Rscript -e 'pkgdown::build_site()'
- name: Deploy to WEBROOT
env:
WEBROOT: ${{ vars.WEBROOT }}
run: |
test -n "$WEBROOT"
mkdir -p "$WEBROOT"
rsync -av --delete docs/* "$WEBROOT"
+17
View File
@@ -0,0 +1,17 @@
name: run tests
run-name: run tests
on:
push:
branches:
- main
jobs:
build-and-deploy-documentation:
runs-on: linux_amd64
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Call to devtools::test()
run: |
Rscript -e 'devtools::test()'
+8
View File
@@ -3,3 +3,11 @@
.Rhistory
.RData
.Ruserdata
.positai
.png
.DS_Store
www/.DS_Store
dev/www/.DS_Store
man
docs
pkgdown
+11
View File
@@ -0,0 +1,11 @@
linters: linters_with_defaults(
line_length_linter(150),
commented_code_linter = NULL,
object_name_linter = NULL,
brace_linter = NULL
)
exclusions: list(
"inst/doc/creating_linters.R" = 1,
"inst/example/bad.R",
"tests/testthat/exclusions-test"
)
+46
View File
@@ -0,0 +1,46 @@
Package: DashboardApp
Type: Package
Title: What the Package Does (Title Case)
Version: 0.1.0
Authors@R: c(
person(
"Franz", "Innerbichler",
email = "f.innerbichler@eclipso.at",
role = c("aut", "cre")
),
person(
"Simon", "Innerbichler",
email = "simon.innerbichler@proton.me",
role = c("aut")
)
)
Description: More about what it does (maybe more than one line).
Continuation lines should be indented.
Imports:
shiny,
shinydashboard,
shinyjs,
shinyAce,
shinycssloaders,
shinyBS,
purrr,
gslnls,
tidyverse,
ggplot2,
reshape2,
openxlsx,
DT,
ggpubr,
gridExtra,
drc,
twopartm,
car,
dplyr,
scales
License: Commercial, all rights reserved
Encoding: UTF-8
LazyData: true
Config/roxygen2/version: 8.0.0
Suggests:
testthat (>= 3.0.0)
Config/testthat/edition: 3
+5
View File
@@ -12,3 +12,8 @@ Encoding: UTF-8
RnwWeave: Sweave
LaTeX: pdfLaTeX
BuildType: Package
PackageUseDevtools: Yes
PackageInstallArgs: --no-multiarch --with-keep.source
PackageRoxygenize: rd,collate,namespace
-432
View File
@@ -1,432 +0,0 @@
---
output:
pdf_document:
extra_dependencies: ["float"]
number_sections: true
toc: true
toc_depth: 3
header_includes:
-\usepackage{fancyheadr}
-\setlength{\headheight}{22pt}%
-\usepackage{lastpage}
-\pagestyle{fancy}
-\usepackage{pdflscape}
-\usepackage{longtable}
-\rhead{\includegraphics[width=.15\textwidth]{`r getwd()`/logo.png}}
params:
FileName: NA
newTitle: NA
author: NA
REP: NA
coeffs: NA
author: "Author: `r params$author`"
title: |
| ![](logo.png){width=1in}
| 4PL bioassay evaluation
subtitle: |
`r params$FileName`
<left> Unique time: </left> <right> `r Sys.time()`</right>
date: "`r paste(params$Subway, params$Version)`"
---
<!-- \fancyfoot[C]{\thepage\ of \pageref{LastPage}} -->
<!-- \newpage -->
<!-- \newpage -->
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(knitr)
library(DT)
REP <- params$REP
author <- params$author
coeffs <- params$coeffs
all_l <- REP$all_l
ANOVAXLS <- REP$ANOVAXLS
DiagnTable <- REP$DiagnTable
UnRPLAausw <- REP$UnRPLAausw
UnRPLBend <- REP$UnRPLBend
PLAausw <- REP$PLAausw
PLBend <- REP$PLBend
LogPLAausw <- REP$LogPLAausw
LogUnrPLAausw <- REP$LogUnrPLAausw
XLdat2 <- REP$XLdat2
CIplot <- REP$CIplot
testsTab <- REP$testsTab
relpotTestPlot <- REP$relpotTestPlot
```
# Introduction
Bioassay potency estimation uses statistical methods to quantify the strength of a biological product or drug by comparing its response to that of a reference standard. Because biological responses are inherently variable, affected by assay conditions, cell systems or organisms, and measurement noise, the 4-parametric logistic regression is used to obtain reliable potency values. The variance for confidence interval calculation is coming from the regression procedure itself and is an excellent predictor for the variability of any future potency determinations.
USP<1034> recommends calculation of standard errors of ratios of the parameters using Fieller's theorem [Finney D.J. 1978] or using the "delta" method (for a discussion about the "delta" method see [Ver Hoef 2012]). However, the presented gradient approach using the differences on the log-scale is methematically more stable und thus preferable compared to any ratio approach ([Franz, V.H. 2007]).
# Results
All data used for the 4PL evaluation is shown in table 1:
```{r alll, echo=FALSE, warning=FALSE, results='asis'}
kable(all_l, format = "markdown", caption= "Uploaded data (test and reference) in long format", digits=3)
```
The following 4 plots show all 4 models: restricted and unrestricted, and log transformed, respectively.
You can also embed plots, for example:
```{r XLplot, echo=FALSE, warning=FALSE, fig.height=4, fig.width=6, fig.cap="Plot of models", fig.align='left'}
plot_f <- function(dat, sigmoid,det_sig) {
CORdat <- cor(dat[,1],dat[,ncol(dat)])
all_l <- melt(data.frame(dat), id.vars="log_dose", variable.name="replname", value.name = "readout")
isRef <- rep(c(1,0),1,each=nrow(all_l)/2)
isSample <- rep(c(0,1),1,each=nrow(all_l)/2)
all_l2 <- cbind(all_l, isRef, isSample)
if(is.null(det_sig)) {
if (CORdat<0) {
startlist <- list(a=sigmoid[3], b=-sigmoid[5],cs=sigmoid[7],
d=sigmoid[1],r=sigmoid[8])
} else {
startlist <- list(a=sigmoid[3],b=sigmoid[5],cs=sigmoid[7],
d=sigmoid[1],r=sigmoid[8])
}
} else {
startlist <- list(a=det_sig[5], b=det_sig[1],cs=det_sig[7],
d=det_sig[3],r=det_sig[7] - det_sig[8])
}
#browser()
tryCatch({
mr <- gsl_nls(fn = readout ~ a+(d-a)/(1+exp(b*(log_dose-(cs-r*isSample)))),
data=all_l2,
start=startlist,
control=gsl_nls_control(xtol=1e-6,ftol=1e-6, gtol=1e-6))
},
error = function(err) {
err$message
})
s_mr <- summary(mr)
a <- s_mr$coefficients[1,1]
b <- s_mr$coefficients[2,1]
cs <- s_mr$coefficients[3,1]
d <- s_mr$coefficients[4,1]
r <- s_mr$coefficients[5,1]
log_dose <- unique(all_l$log_dose)
seq_x <- seq(min(log_dose),max(log_dose),0.1)
SAMPLE <- a+(d-a)/(1+exp(b*(seq_x-(cs-r))))
REF <- a+(d-a)/(1+exp(b*(seq_x-(cs))))
if (is.null(det_sig)) {
SAMPLEtrue <- sigmoid[4] + (sigmoid[2] -sigmoid[4])/(1+exp(sigmoid[6]*(seq_x-(sigmoid[7]-sigmoid[8]))))
REFtrue <- sigmoid[3] + (sigmoid[1] -sigmoid[3])/(1+exp(sigmoid[5]*(seq_x-(sigmoid[7]))))
} else {
SAMPLEtrue <- det_sig[4] + (det_sig[6] -det_sig[4])/(1+exp(-det_sig[2]*(seq_x-(det_sig[8]))))
REFtrue <- det_sig[3] + (det_sig[5] -det_sig[3])/(1+exp(-det_sig[1]*(seq_x-(det_sig[7]))))
}
pl_df <- cbind(seq_x, SAMPLE, REF, SAMPLEtrue, REFtrue)
all_l2$readout[all_l2$readout < 0] <- 0.01
all_l2$readouttrans <- log(all_l2$readout)
slopeEC50 <- b*(a-d)/4
Xbendl3 <- cs-(1.31696/b)
Xbendu3 <- cs+(1.31696/b)
XbendlT <- cs-r-(1.31696/b)
XbenduT <- cs-r+(1.31696/b)
bendpoints <- c(bendREF_lower = round(Xbendl3,3), bendREF_upper=round(Xbendu3,3),
bendSAMPLE_lower = round(XbendlT,3), bendSAMPLE_upper=round(XbenduT,3))
p <- ggplot(all_l2, aes(x=log_dose, y=readout, color=factor(isRef))) +
geom_point(shape=factor(isRef), alpha=0.8) +
labs(title = paste("restricted 4pl; bendp:", round(Xbendl3,3),round(Xbendu3,3),round(XbendlT,3),round(XbenduT,3)),
color="product") +
scale_color_manual(labels=c("test","reference"), values=c("red","blue")) +
scale_shape_manual(labels=c("test","reference")) +
theme_bw() +
theme(axis.text = element_text(size=14))
p2 <- p + geom_line(data=as.data.frame(pl_df), aes(x=seq_x, y=SAMPLE), color="red",
inherit.aes = F) +
geom_line(data=as.data.frame(pl_df), aes(x=seq_x, y=REF), color="blue",
inherit.aes = F) +
geom_line(data=as.data.frame(pl_df), aes(x=seq_x, y=SAMPLEtrue), color="red", linetype=2, alpha=0.4,
inherit.aes = F) +
geom_line(data=as.data.frame(pl_df), aes(x=seq_x, y=REFtrue), color="blue", linetype=2, alpha=0.4,
inherit.aes = F) +
geom_vline(xintercept=c(Xbendl3, Xbendu3), col="blue",linetype=2) +
geom_vline(xintercept=c(XbendlT, XbenduT), col="red",linetype=2) +
annotate("text", x=cs, y=a+(d-a)/2, label="0", size=5) +
theme(legend.position="none")
# transformed plots
p_rt <- ggplot(all_l2, aes(x=log_dose, y=readouttrans, color=factor(isRef))) +
geom_point(shape=factor(isRef), alpha=0.8) +
labs(title = paste("restricted transformed 4pl"), color="product") +
scale_color_manual(labels=c("test","reference"), values=c("red","blue")) +
theme_bw()
mrt <- gsl_nls(fn = readouttrans ~ a+(d-a)/(1+exp(b*(log_dose-(cs-r*isSample)))),
data=all_l2,
start=startlist,
control=gsl_nls_control(xtol=1e-6,ftol=1e-6, gtol=1e-6))
s_mrt <- summary(mrt)
a_trans <- s_mrt$coefficients[1,1]
b_trans <- s_mrt$coefficients[2,1]
cs_trans <- s_mrt$coefficients[3,1]
d_trans <- s_mrt$coefficients[4,1]
r_trans <- s_mrt$coefficients[5,1]
XbendlTrans <- cs_trans-(1.31696/b_trans)
XbenduTrans <- cs_trans+(1.31696/b_trans)
XbendlTransT <- cs_trans-r_trans-(1.31696/b_trans)
XbenduTransT <- cs_trans-r_trans+(1.31696/b_trans)
bendpointsTRANS <- c(bendREF_lower = round(XbendlTrans,3), bendREF_upper=round(XbenduTrans,3),
bendSAMPLE_lower = round(XbendlTransT,3), bendSAMPLE_upper=round(XbenduTransT,3))
SAMPLEtrans <- a_trans+(d_trans-a_trans)/(1+exp(b_trans*(seq_x-(cs_trans-r_trans))))
REFtrans <- a_trans+(d_trans-a_trans)/(1+exp(b_trans*(seq_x-(cs_trans))))
pl_df_trans <- cbind(seq_x, SAMPLEtrans, REFtrans)
p_rt2 <- p_rt + geom_line(data=as.data.frame(pl_df_trans), aes(x=seq_x, y=SAMPLEtrans), color="red",
inherit.aes = F) +
geom_line(data=as.data.frame(pl_df_trans), aes(x=seq_x, y=REFtrans), color="blue",
inherit.aes = F) +
geom_vline(xintercept=c(XbendlTrans, XbenduTrans), col="blue",linetype=2) +
geom_vline(xintercept=c(XbendlTransT, XbenduTransT), col="red",linetype=2) +
theme(legend.position = "none", axis.text=element_text(size=14))
if (is.null(det_sig)) {
unrestr <- drm(readout ~ exp(log_dose), isSample, data=all_l2, fct=LL.4(),
pmodels=data.frame(isSample, isSample,isSample,isSample))
Sum_u <- summary(unrestr)
ast <- Sum_u$coefficients[3,1]
ate <- Sum_u$coefficients[4,1]
bst <- Sum_u$coefficients[1,1]
bte <- Sum_u$coefficients[2,1]
cst <- log(Sum_u$coefficients[7,1])
cte <- log(Sum_u$coefficients[8,1])
dst <- Sum_u$coefficients[5,1]
dte <- Sum_u$coefficients[6,1]
} else {
ast <- det_sig[5]
ate <- det_sig[6]
bst <- det_sig[1]
bte <- det_sig[2]
cst <- det_sig[7]
cte <- det_sig[8]
dst <- det_sig[3]
dte <- det_sig[4]
}
REFu <- ast + (dst-ast)/(1+exp(bst*(seq_x-cst)))
SAMPLEu <- ate + (dte-ate)/(1+exp(bte*(seq_x-cte)))
pl_df2 <- cbind(seq_x, SAMPLEu, REFu)
#browser()
pu <- ggplot(all_l2, aes(x=log_dose, y=readout, color=factor(isRef))) +
geom_point() +
labs(title="unrestricted 4_pl-Model", color="product") +
scale_color_manual(labels = c("test","reference"), values=c("red","blue")) +
theme_bw()
pu2 <- pu + geom_line(data=as.data.frame(pl_df2), aes(x=seq_x, y=SAMPLEu),
color="red", inherit.aes = F) +
geom_line(data=as.data.frame(pl_df2), aes(x=seq_x, y=REFu),
color="blue", inherit.aes = F,
show.legend = F)
pu2_ <- pu2 +
theme(legend.position = "none", axis.text = element_text(size=14))
putrans <- ggplot(all_l2, aes(x=log_dose, y=readouttrans, color=factor(isRef))) +
geom_point() +
labs(title="unrestricted transformed 4_pl-Model", color="product") +
scale_color_manual(labels = c("test","reference"), values=c("red","blue")) +
theme_bw()
unrestr_trans <- drm(readouttrans ~ exp(log_dose), isSample, data=all_l2, fct=LL.4(),
pmodels=data.frame(isSample, isSample,isSample,isSample))
Sum_ut <- summary(unrestr_trans)
ast_t <- Sum_ut$coefficients[3,1]
ate_t <- Sum_ut$coefficients[4,1]
bst_t <- Sum_ut$coefficients[1,1]
bte_t <- Sum_ut$coefficients[2,1]
cst_t <- log(Sum_ut$coefficients[7,1])
cte_t <- log(Sum_ut$coefficients[8,1])
dst_t <- Sum_ut$coefficients[5,1]
dte_t <- Sum_ut$coefficients[6,1]
REFu_trans <- ast_t + (dst_t-ast_t)/(1+exp(bst_t*(seq_x-cst_t)))
SAMPLEu_trans <- ate_t + (dte_t-ate_t)/(1+exp(bte_t*(seq_x-cte_t)))
pl_df2u_t <- cbind(seq_x, SAMPLEu_trans, REFu_trans)
pu2_t <- putrans + geom_line(data=as.data.frame(pl_df2u_t), aes(x=seq_x, y=SAMPLEu_trans),
color="red", inherit.aes = F) +
geom_line(data=as.data.frame(pl_df2u_t), aes(x=seq_x, y=REFu_trans),
color="blue", inherit.aes = F,
show.legend = F)
pu3_t <- pu2_t
grid.arrange(p2,p_rt2,pu2_,pu3_t, nrow=2)
}
plot_f(XLdat2, sigmoid=NULL, det_sig=coeffs)
```
The ANOVA of the unconstrained model is listed in table 2:
```{r anovaxls, echo=FALSE, warning=FALSE, results='asis'}
kable(ANOVAXLS, format = "markdown", caption= "ANOVA table unrestricted", digits=3)
```
```{r SST_ergebn, fig.align='center', fig.pos='htb!', echo=FALSE, cache=FALSE, warning=FALSE, message=FALSE, tidy=TRUE}
kable(testsTab[1:7,], row.names = F, format = "markdown", caption="SST results")
```
*...The estimate for F-test on regression and on non-linearity is the p-value
F-test on regression passes if F-value > F-crit and thus p < 0.05
F-test on non-linearity passes if F-value < F-crit and thus p > 0.05
Test results outcome:
0 ... test passed (for EQ tests: CI within limits);
1 ... test failed (for EQ tests CI not within limits);
-1 ... calculations unbound/denominator too close to 0
<!-- ```{r, label= 'CIplot', echo=FALSE, warning=FALSE, fig.width=100, fig.cap='Selected SSt confidence intervals with entered limits', fig.align='center'} -->
<!-- png("CIplot.png") -->
<!-- print(CIplot) -->
<!-- dev.off() -->
<!-- ``` -->
<!-- ![](CIplot.png){width=60%} -->
## Fitting results of the 4 models with bend points
The results of the non-linear fitting procedure for the restricted model (5 parameters) is listed in table 4:
```{r PLAausw, echo=FALSE, warning=FALSE, results='asis'}
kable(PLAausw, format = "markdown", caption= "Restricted 4PL evaluation", digits=3, row.names = F)
```
A depiction of the CI and corresponding limits of relative potency is shown here:
```{r, label='relpotPlot', echo=FALSE, warning=FALSE, fig.height=2, fig.width=3.5, fig.cap="Rel potency with CIs and limits", fig.align='left', results='asis'}
print(relpotTestPlot)
```
The bend points for test and reference sample are in table 5:
```{r PLBend, echo=FALSE, warning=FALSE, results='asis'}
kable(PLBend, format = "markdown", caption= "Bendpoints (Sebaugh) of restricted 4PL", digits=3)
```
The results of the non-linear fitting procedure for the unrestricted model (8 parameters) is listed in table 6:
```{r UnRPLAausw, echo=FALSE, warning=FALSE, results='asis'}
kable(UnRPLAausw, format = "markdown", caption= "UNrestricted 4PL evaluation", digits=3, row.names = F)
```
```{r UnRPLBend, echo=FALSE, warning=FALSE, results='asis'}
kable(UnRPLBend, format = "markdown", caption= "Bend points of 4PL unrestricted", digits=3, row.names = F)
```
```{r LogPLAausw, echo=FALSE, warning=FALSE, results='asis'}
kable(LogPLAausw, format = "markdown", caption= "Restricted 4PL evaluation with log-transformed response", digits=3)
```
```{r LogUnRPLAausw, echo=FALSE, warning=FALSE, results='asis'}
kable(LogUnrPLAausw, format = "markdown", caption= "Unrestricted 4PL evaluation with log-transformed response", digits=3)
```
# Appendix: Formulas
## 4PL regression
$$
Y = D + \frac{A-D} {1+(\frac{C} {x})^B } + \epsilon
$$
## log-logistic 4P regression
$$
Y = D + \frac{A-D} {1+e^{(B*(C - log(x))) }} + \epsilon
$$
where: x ... concentration of the analyte
A: upper asymptote
B: slope
D: lower asymptote
C ... EC50
# Literature
Finney, D.J.: (1978) Statistical Method in Biological Assay, London: Charles Griffin House, 3rd edition (pp. 80-82)
Franz, V.H.: Ratios: A short guide to confidence limits and proper use. arXiv:0710.2024v1, 10 Oct 2007
VerHoef, J.M.: Who invented the Delta Method? The American Statistician, 2012, 66:2, 124-127 DOI: 10.1080/00031305.2012.687494
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Vendored
BIN
View File
Binary file not shown.
+1520
View File
File diff suppressed because it is too large Load Diff
+59
View File
@@ -0,0 +1,59 @@
---
title: "RoxygenFileTest"
author: "F Innerbichler"
date: "2026-05-13"
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(shiny)
source("Global.R")
library(testthat)
```
```{r LinPotTab, echo=F}
library(car)
CIRC <- data.frame(log_dose = c(-2.5,-2.5,-2.5, -3.2,-3.2,-3.2,-3.9,-3.9,-3.9,
-3.2,-3.2,-3.2,-3.9,-3.9,-3.9,-4.7,-4.7,-4.7),
replname= c("R_dil1","R_dil1","R_dil1", "R_dil2","R_dil2","R_dil2", "R_dil3","R_dil3","R_dil3",
"T_dil1","T_dil1","T_dil1", "T_dil2","T_dil2","T_dil2", "T_dil3","T_dil3","T_dil3"),
readout = c(72.1,75.8,76.04,59.8,61,62.7,43.6,45,41.5,53.5,62.2,65.9,48.3,43.8,43.14,28.17,29.2,31.2),
isRef=c(rep(1,9), rep(0,9)),
isSample = c(rep(0,9), rep(1,9)))
Lim <- c(rep(0,8), 70,130)
PureErrF <- TRUE
TestTab <- as.matrix(LinPotTab(circles=CIRC, Lim, PureErrF))
# SolTab is the Solution table
SolTab <- matrix(c(104.959, 87.994, 125.196, 0, 83.836, 119.281),nrow=1)
colnames(SolTab) <- c("Potency", "lower 95%CI", "upper 95%CI", "test_result", "lowerRel95%CI", "upperRel95%CI")
#all.equal(TestTab, SolTab)
expect_equal(TestTab, SolTab, check.attributes = FALSE)
# no output means "all_equal"
```
```{r pressure, echo=FALSE}
```
Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.
``` {r}
y<-1:4;mean(y)
#> [1] 2.5
```
+9
View File
@@ -0,0 +1,9 @@
SCRUM jobs
*) Sessioninfo geht noch ins Leere:
tabPanel("Configuration",
verbatimTextOutput("sessioninfo"))
*) Checks ob EXCEL file den Vorgaben entspricht:
**) Mindestens 2 Referenz- und gleich viele Testsample Spalten.
**) Check ob Spalte mit den Verdünnungen den regex Vorgaben entspricht (Ind <- grep("dilu | dose | Dose | Conc | conc",cn)
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
template:
bootstrap: 5
BIN
View File
Binary file not shown.
+265
View File
@@ -0,0 +1,265 @@
---
output:
pdf_document:
extra_dependencies: ["float"]
number_sections: true
toc: true
toc_depth: 3
header_includes:
-\setlength{\headheight}{22pt}%
-\usepackage{pdflscape}
-\usepackage{longtable}
-\usepackage{fancyheadr}
-\pagestyle{fancy}
-\fancyhf{}
-\fancyfoot[C]{Page \thepage \ of \pageref{LastPage}}
-\usepackage{lastpage}
-\rhead{\includegraphics[width=.15\textwidth]{`r getwd()`/logov2.png}}
params:
FileName: NA
newTitle: NA
author: NA
REP: NA
REPlin: NA
coeffsLin: NA
NoP: NA
Assay: NA
author: "Author: `r params$author`"
title: |
| ![](logov2.png){width=1in}
| Linear bioassay evaluation
subtitle: |
`r params$FileName`
<left> Unique time: </left> <right> `r Sys.time()`</right>
date: "`r paste(params$NoP, params$Assay)`"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(knitr)
library(DT)
REP <- params$REP
REPlin <- params$REPlin
author <- params$author
coeffsLin <- params$coeffsLin
all_l <- REP$all_l
circles <- REPlin$circles
#ANOVAXLS <- REP$ANOVAXLS
SuModAB <- REPlin$SuModAB
SuModABu <- REPlin$SuModABu
LinTests <- REPlin$LinTests
XLplotLin <- REPlin$pLin
LinPotTab <- REPlin$LinPotTab
XLdat2 <- REP$XLdat2
LinTests1 <- LinTests[,1:3]
ANOVAlin <- LinTests[,4:ncol(LinTests)]
```
\newpage
# Introduction
Bioassay potency estimation uses statistical methods to quantify the strength of a biological product or drug by comparing its response to that of a reference standard. Biological responses are inherently variable, affected by assay conditions, cell systems or organisms, and measurement noise. To control this variability, a linear regression approach is used to obtain reliable potency values. Three consecutive dilution steps showing the steepest slope are used for linear fitting.
USP<1034> recommends calculation of standard errors of ratios of the parameters using Fieller's theorem [Finney D.J. 1978] or using the "delta" method (for a discussion about the "delta" method see [Ver Hoef 2012]). The present analysis calculated the relative potency with the "delta" method. The formula of the relative potency is in the Appendix.
# Raw data
All data used for evaluation is shown in table 1.
```{r Alll, echo=FALSE, warning=FALSE, results='asis'}
kable(XLdat2, format = "markdown", caption= "Uploaded data (test and reference) ", digits=3)
```
The linerar regression is calculated on the readout listed in table 2.
```{r Circles, echo=FALSE, warning=FALSE, results='asis'}
kable(circles, format = "markdown", caption= "Concentrations and readout used for linear regression", digits=3, row.names = F)
```
# Results
## Overall result
```{r Over_all, echo=FALSE, comment=NA, warning=NA, message=NA}
#browser()
potFlag <- 0
if (LinPotTab[1,"test_result"]==1) potFlag <- 1
AnalysisFlag <- FALSE
if (potFlag==1 | sum(LinTests$test_results)>0) AnalysisFlag <- TRUE
colFmt <- function() {
outputFormat <- knitr::opts_knit$get("rmarkdown.pandoc.to")
if(AnalysisFlag) {
text <- paste("\\textcolor{red}{Analysis failed}",sep="")
} else {
text <- paste("\\textcolor{black}{Analysis succeeded}",sep="")
}
return(text)
}
```
`r colFmt()`
## Plots and ANOVA
Plots in Figure 1 show the restricted and unrestricted model, respectively.
```{r LinPlot, echo=FALSE, warning=FALSE, fig.height=4, fig.width=6, fig.cap="Plot of models", fig.align='left'}
library(cowplot)
plot_grid(XLplotLin)
```
The relative potency can be read from tabale 3.
```{r LinPotTab, echo=FALSE, warning=FALSE, results='asis'}
kable(LinPotTab, format = "markdown", caption= "Potency table", digits=3)
```
0 ... test passed;
1 ... test failed);
The ANOVA of the unconstrained model is listed in table 4.
```{r anovaxls, echo=FALSE, warning=FALSE, results='asis'}
kable(ANOVAlin, format = "markdown", caption= "ANOVA table unrestricted", digits=3)
RMSE <- sqrt(ANOVAlin[5,4])
```
The standard deviation of the model is `r RMSE`.
The assay suitability tests are shown in table 5.
```{r SST_ergebn, echo=FALSE, cache=FALSE, warning=FALSE, message=FALSE, tidy=TRUE}
kable(LinTests1, row.names = F, format = "markdown", caption="Assay suitability test results", digits=3)
```
The estimate is the p-value of the test.
F-tests on regression, significance of slopes, and preparation need to have a p-value <0.05 to pass.
All other tests pass if p-value > 0.05.
0 ... test passed;
1 ... test failed);
(NOTE: F-tests are sensitive, when the residual variability of the method is small. On the other hand effects may not be detected if residual variability is high.)
## Fitting results
The results of the linear fitting procedure for the restricted model is listed in table 6:
```{r SumCSSI, echo=FALSE, warning=FALSE, results='asis'}
kable(SuModAB, format = "markdown", caption= "Restricted linear regression (CSSI)", digits=3, row.names = F)
```
CSSI: common slope, separate intercept
The results of the linear fitting procedure for the unrestricted model is listed in table 7.
```{r SumSSSI, echo=FALSE, warning=FALSE, results='asis'}
kable(SuModABu, format = "markdown", caption= "Restricted linear regression (SSSI)", digits=3, row.names = F)
```
SSSI: separate slope, separate intercept
# Signature
<!-- Signature and date:\\ -->
<!-- \noindent\framebox(200,50) -->
<!-- \begin{minipage}[t][40pt][c]{190pt} -->
<!-- \centering -->
<!-- % Leave this blank for a physical signature -->
<!-- \end{minipage} -->
\vspace{1.5cm}
\noindent
\begin{tabular}{p{6cm}p{1cm}p{6cm}}
\cline{1-1} \cline{3-3}
Date & & Signature
\end{tabular}
# Appendix: Formulas
## Potency of linear PLA
Relative potency of the test sample to the reference is calculated as:
$$
relPot_{log} = \frac{I_{ref} - I_{test}}{k}
$$
where: \\ I... intercept of reference or test\\
k ... common slope
The standard error of the linear restricted model is used to get the confidence interval of the relative potency with the formula:
$$
CI_{rel Pot} = exp(relPot_{log} \pm se(relPot_{log})*q^{t_{n-p}}_{1-\frac{\alpha}{2}})
$$
In general, the confidence intervals are calculated as follows:
$$
CI = \hat\theta\pm se(\hat\theta)*q^{t_{n-p}}_{1-\frac{\alpha}{2}}
$$
…where $\hat\theta$ is a fitted parameter or a linear combination thereof, q is the 1-alpha/2 quantile of the Students t-distribution with n-p degrees of freedom and se is the standard error derived from any covariance matrix.
# Literature
Finney, D.J.: (1978) Statistical Method in Biological Assay, London: Charles Griffin House, 3rd edition (pp. 80-82)
Franz, V.H.: Ratios: A short guide to confidence limits and proper use. arXiv:0710.2024v1, 10 Oct 2007
VerHoef, J.M.: Who invented the Delta Method? The American Statistician, 2012, 66:2, 124-127 DOI: 10.1080/00031305.2012.687494
+331
View File
@@ -0,0 +1,331 @@
---
output:
pdf_document:
extra_dependencies: ["float"]
number_sections: true
toc: true
toc_depth: 3
header_includes:
-\usepackage{fancyheadr}
-\setlength{\headheight}{22pt}%
-\usepackage{lastpage}
-\pagestyle{fancy}
-\usepackage{pdflscape}
-\usepackage{longtable}
-\rhead{\includegraphics[width=.15\textwidth]{`r getwd()`/logov2.png}}
params:
FileName: NA
author: NA
NoP: NA
Assay: NA
REP: NA
coeffs: NA
author: "Author: `r params$author`"
title: |
| ![](logov2.png){width=1in}
| 4PL bioassay evaluation
subtitle: |
`r params$FileName`
<left> Unique time: </left> <right> `r Sys.time()`</right>
date: "`r paste(params$NoP, params$Assay)`"
---
<!-- \fancyfoot[C]{\thepage\ of \pageref{LastPage}} -->
<!-- \newpage -->
<!-- \newpage -->
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(knitr)
library(DT)
library(kableExtra)
REP <- params$REP
author <- params$author
coeffs <- params$coeffs
all_l <- REP$all_l
ANOVAXLS <- REP$ANOVAXLS
XLplot4pl <- REP$XLplot4pl
DiagnTable <- REP$DiagnTable
UnRPLAausw <- REP$UnRPLAausw
UnRPLBend <- REP$UnRPLBend
PLAausw <- REP$PLAausw
PLbend <- REP$PLBend
pottab4plXL <- REP$pottab4plXL
Lim <- REP$Lim
XLdat2 <- REP$XLdat2
PureErr <- REP$PureErr
CIplot <- REP$CIplot
testsTab <- REP$testsTab
relpotTestPlot <- REP$relpotTestPlot
#browser()
```
# Introduction
Bioassay potency estimation uses statistical methods to quantify the strength of a biological product or drug by comparing its response to that of a reference standard. Because biological responses are inherently variable, affected by assay conditions, cell systems or organisms, and measurement noise, the 4-parametric logistic regression is used to obtain reliable potency values.
USP<1034> recommends calculation of standard errors of ratios of the parameters using Fieller's theorem [Finney DJ 1978] or using the "delta" method (for a discussion about the "delta" method see [Ver Hoef 2012]). However, the presented gradient approach using the differences on the log-scale is mathematically more stable und thus preferable compared to a ratio approach ([Franz VH 2007]).
# Raw data
All data used for the 4PL evaluation is shown in table 1:
```{r alll, echo=FALSE, warning=FALSE, results='asis'}
kable(XLdat2, format = "markdown", caption= "Uploaded data (test and reference) ", digits=3)
```
# Results
## Overall result
```{r Over_all, echo=FALSE, comment=NA, warning=NA, message=NA}
# browser()
potFlag <- 0
if (pottab4plXL["test_result"][[1]][1]==1) potFlag <- 1
AnalysisFlag <- FALSE
if (potFlag==1 | sum(testsTab$test_results)>0) AnalysisFlag <- TRUE
colFmt <- function() {
outputFormat <- knitr::opts_knit$get("rmarkdown.pandoc.to")
if(AnalysisFlag) {
text <- paste("\\textcolor{red}{Analysis failed}",sep="")
} else {
text <- paste("\\textcolor{black}{Analysis succeeded}",sep="")
}
return(text)
}
```
`r colFmt()`
## 4pl-regression
Relative potency (absolute and relative confidence limits) are shown in Table 2. `r if(PureErr) {"Pure Error is used for calculations."}`
`r if (!PureErr) {"RMSE of restricted model is used for confidence limit calculation."}`
```{r Pot_tab4pl, echo=FALSE, comment=NA, warning=NA, message=NA}
#browser()
if (pottab4plXL["test_result"][[1]][1]==1) { cat(paste("FAILED: relative potency CL result of restricted model outside limits: ", Lim[[9]], "to" ,Lim[[10]] ))}
if (pottab4plXL["test_result"][[1]][1]==0) { cat(paste("PASSED: relative potency CL result of restricted model within limits: ", Lim[[9]], "to" ,Lim[[10]] ))}
kable(pottab4plXL, format = "markdown", caption= "Relative potency with absolute and relative CLs ", digits=3, row.names = F) %>%
kable_styling(latex_options = "hold_position")
```
NOTE: results of unrestricted model for Information only.
## Plot of the data and models
Plots in Figure 1 show the restricted and unrestricted model, respectively.
```{r XLplot, echo=FALSE, warning=FALSE, fig.height=4, fig.width=6, fig.cap="Plot of models", fig.align='left', comment=F, message=F, results='asis', fig.pos='H'}
library(cowplot)
plot_grid(XLplot4pl)
```
## ANOVA table
The ANOVA of the unconstrained model is listed in table 3. Bates and Watts proposed a test on parallelism which compares the residual sum of squares of the restricted model (ResRSSE) with the residual sum of squares of the unrestricted model (UnresRSSE). If the UnresRSSE is significantly smaller than the ResRSSE, the p-value of "Non-parallelism" is smaller than 0.05 (line 4 in table 3). This test is for information only as it may be overly sensitive in case of small overall variability of the data.
```{r anovaxls, echo=FALSE, warning=FALSE, results='asis'}
kable(ANOVAXLS, format = "markdown", caption= "Analysis of variance", digits=3) %>%
kable_styling(latex_options = "hold_position")
```
## Assay suitability tests
Table 4 lists the chosen suitability test results with confidence limits, where applicable. F-tests should be read with caution, if the overall variability is small, as the test gets overly sensitive.
```{r SST_ergebn, echo=FALSE, cache=FALSE, warning=FALSE, message=FALSE, tidy=TRUE}
kable(testsTab, row.names = F, format = "markdown", caption="Assay suitability results", digits=4)
```
\footnotesize
```{r Fussnote, echo=F, comment=NA}
cat("*...The estimate for F-test on regression and on non-linearity is the p-value")
cat( "F-test on regression passes if F-value > F-crit and thus p < 0.05")
cat( "F-test on non-linearity passes if F-value < F-crit and thus p > 0.05")
cat( "Test results outcome:")
cat(" 0 ... test passed (for EQ tests: CL within limits);")
cat(" 1 ... test failed (for EQ tests: CL not within limits);")
```
\normalsize
```{r AST_Ergebn, echo=FALSE, cache=FALSE, warning=FALSE, message=FALSE, tidy=TRUE}
TestsTabFlag <- FALSE
if (sum(testsTab$test_results)>0) TestsTabFlag <- TRUE
colFmt2 <- function() {
outputFormat <- knitr::opts_knit$get("rmarkdown.pandoc.to")
if(TestsTabFlag) {
text <- paste("\\textcolor{red}{Assay suitability tests failed}",sep="")
} else {
text <- paste("\\textcolor{black}{Assay suitability tests succeeded}",sep="")
}
return(text)
}
```
`r colFmt2()`
## Fitting results with curve points
The results of the non-linear fitting procedure for the restricted model (5 parameters) is listed in table 5:
```{r PLAausw, echo=FALSE, warning=FALSE, results='asis'}
kable(PLAausw, format = "markdown", caption= "Restricted 4PL model", digits=3, row.names = F)
```
Sebaugh et al proposed bend points for test and reference samples, that define the points with highest turning behavior. Table 6 lists these bendpoints as well as asymptote points ~ twice as far from the center as the bendpoints.
```{r PLBend, echo=FALSE, warning=FALSE, results='asis'}
kable(PLbend, format = "markdown", caption= "Bendpoints and asymptote points of restricted 4PL model", digits=3)
```
The results of the non-linear fitting procedure for the unrestricted model (8 parameters) is listed in table 7:
```{r UnRPLAausw, echo=FALSE, warning=FALSE, results='asis'}
kable(UnRPLAausw, format = "markdown", caption= "Unrestricted 4PL model", digits=3, row.names = F)
```
# Signature
\vspace{1.5cm}
\noindent
\begin{tabular}{p{6cm}p{1cm}p{6cm}}
\cline{1-1} \cline{3-3}
Date & & Signature
\end{tabular}
\newpage
# Appendix: Formulas
## 4PL regression
$$
Y = D + \frac{A-D} {1+(\frac{C} {x})^B } + \epsilon
$$
where: x ... concentration of the analyte
A: upper asymptote
B: slope
D: lower asymptote
C ... EC50
## log-logistic 4P regression
$$
Y = D + \frac{A-D} {1+e^{(B*(C - log(x))) }} + \epsilon
$$
## Intercept for slope at EC50
$$
I = A+\frac{D-A}{2}-B_{true}*EC50
$$
## Slope at EC50
$$
B_{true}=B*\frac{D-A}{4}
$$
## Confidence intervals
In general, the confidence intervals are calculated as follows:
$$
CI = \hat\theta\pm se(\hat\theta)*q^{t_{n-p}}_{1-\frac{\alpha}{2}}
$$
…where $\hat\theta$ is a fitted parameter or a linear combination thereof, q is the 1-alpha/2 quantile of the Students t-distribution with n-p degrees of freedom and se is the standard error derived from any covariance matrix.
Let $\theta$ be the 4+1 parameters of the fit (a, b, d, EC50 of reference and EC50 difference). It can be shown that the least squares estimator $\hat\theta$ is normally distributed with asymptotic covariance matrix. The gradient method provides one of several ways to calculate the covariance matrix:
$$
\hat{V(\theta)}= \sigma^2(A(\hat\theta)^T*A(\hat\theta))^{-1}
$$
where A($\theta$) is the n x p matrix of the first partial derivatives for each parameter (i.e. gradient) realized at the fitted parameter estimates. The RMSE of the model or the pure error is used as estimate of $\sigma$. The square root of the diagonals of $\hat{V(\theta)}$ gives the standard errors and with that confidence intervals (CI) can be computed.
# Literature
Finney, D.J.: (1978) Statistical Method in Biological Assay, London: Charles Griffin House, 3rd edition (pp. 80-82)
Franz, V.H.: Ratios: A short guide to confidence limits and proper use. arXiv:0710.2024v1, 10 Oct 2007
VerHoef, J.M.: Who invented the Delta Method? The American Statistician, 2012, 66:2, 124-127 DOI: 10.1080/00031305.2012.687494
Bates, D.M., Watts, D.G. (1988). Comparing models. In: Nonlinear Regression Analysis and Its Applications. New York: Wiley, pp 103-108
Bates, D.M., Watts, D.G. (1988) 2. In: Nonlinear Regression Analysis and Its Applications. New York: Wiley, pp 52-58
+2795
View File
File diff suppressed because it is too large Load Diff
View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

+118
View File
@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="10mm"
height="10mm"
viewBox="0 0 10 10"
version="1.1"
id="svg1"
inkscape:export-filename="logov2.png"
inkscape:export-xdpi="1300.48"
inkscape:export-ydpi="1300.48"
inkscape:version="1.4.4 (dcaf3e7d9e, 2026-05-05)"
sodipodi:docname="logov2.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showguides="true"
inkscape:zoom="23.455313"
inkscape:cx="9.5500753"
inkscape:cy="17.885074"
inkscape:window-width="1267"
inkscape:window-height="1400"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
inkscape:export-bgcolor="#ffffffff">
<sodipodi:guide
position="4.9999999,9.9999997"
orientation="-1,0"
id="guide1"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" />
<sodipodi:guide
position="0,4.9999999"
orientation="0,1"
id="guide2"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" />
<sodipodi:guide
position="0,1.9999999"
orientation="0,1"
id="guide3"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" />
<sodipodi:guide
position="0,7.9999998"
orientation="0,1"
id="guide4"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" />
<sodipodi:guide
position="0.49999999,9.9999997"
orientation="-1,0"
id="guide5"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" />
<sodipodi:guide
position="9.4999997,9.9999997"
orientation="-1,0"
id="guide6"
inkscape:locked="false"
inkscape:label=""
inkscape:color="rgb(0,134,229)" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<circle
style="fill:#418fb7;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-opacity:1"
id="path2"
cx="5"
cy="5"
r="3.4559603" />
<circle
style="display:inline;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.7;stroke-dasharray:none;stroke-opacity:1"
id="circle8"
cx="5"
cy="5"
r="3.4559603" />
<circle
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.3;stroke-opacity:1;stroke-dasharray:none"
id="circle7"
cx="5"
cy="5"
r="3.4559603" />
<path
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.7;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
d="m 0.5,8 c 4,0 5.0000001,-5.9999999 9,-6"
id="path7"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.3;stroke-linecap:round;stroke-dasharray:none;stroke-opacity:1"
d="m 0.5,8 c 4,0 5.0000001,-5.9999999 9,-6"
id="path6"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

+20
View File
@@ -0,0 +1,20 @@
library(shiny)
library(shinydashboard)
library(shinyjs)
library(shinyAce)
library(shinycssloaders)
library(shinyBS)
library(purrr)
library(gslnls)
library(tidyverse)
library(ggplot2)
library(reshape2)
library(openxlsx)
library(DT)
library(ggpubr)
library(gridExtra)
library(drc)
library(twopartm)
library(car)
library(dplyr)
library(scales)
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More