Burton P, Wilson R, Butters O, Ryser-Welch P, Westerberg A, Abarrategui L, Villegas-Diaz R, Avraam D, Wheater S (2025).
dsBaseClient: DataSHIELD Client Functions.
-R package version 6.3.1.
+R package version 6.3.2.
@Manual{,
title = {dsBaseClient: DataSHIELD Client Functions},
- author = {DataSHIELD Developers},
- year = {2024},
- note = {R package version 6.3.1},
+ author = {Paul Burton and Rebecca Wilson and Olly Butters and Patricia Ryser-Welch and Alex Westerberg and Leire Abarrategui and Roberto Villegas-Diaz and Demetris Avraam and Stuart Wheater},
+ year = {2025},
+ note = {R package version 6.3.2},
}
In formula most shortcut notation for formulas allowed under R's standard glm()
function is also allowed by ds.glm.
Many GLMs can be fitted very simply using a formula such as:
-
$$y~a+b+c+d$$
+
\(y~a+b+c+d\)
which simply means fit a GLM with y as the outcome variable and
a, b, c and d as covariates.
By default all such models also include an intercept (regression constant) term.
Instead, if you need to fit a more complex
model, for example:
-
$$EVENT~1+TID+SEXF*AGE.60$$
+
\(EVENT~1+TID+SEXF*AGE.60\)
In the above model the outcome variable is EVENT
and the covariates
TID (factor variable with level values between 1 and 6 denoting the period time),
@@ -237,7 +237,7 @@
Details
The data argument avoids you having to specify the name of the
data frame in front of each covariate in the formula.
For example, if the data frame is called DataFrame you
-avoid having to write: \(DataFrame$y ~ DataFrame$a + DataFrame$b + DataFrame$c + DataFrame$d\)
+avoid having to write: \(DataFrame\$y ~ DataFrame\$a + DataFrame\$b + DataFrame\$c + DataFrame\$d\)
The checks argument verifies that the variables in the model are all defined (exist)
on the server-side at every study
and that they have the correct characteristics required to fit the model.
@@ -427,11 +427,11 @@
In formula Most shortcut notation for formulas allowed under R's standard glm()
function is also allowed by ds.glmSLMA.
Many glms can be fitted very simply using a formula such as:
-
$$y~a+b+c+d$$
+
\(y~a+b+c+d\)
which simply means fit a glm with y as the outcome variable and
a, b, c and d as covariates.
By default all such models also include an intercept (regression constant) term.
Instead, if you need to fit a more complex
model, for example:
-
$$EVENT~1+TID+SEXF*AGE.60$$
+
\(EVENT~1+TID+SEXF*AGE.60\)
In the above model the outcome variable is EVENT
and the covariates
TID (factor variable with level values between 1 and 6 denoting the period time),
@@ -355,7 +355,7 @@
Details
The dataName argument avoids you having to specify the name of the
data frame in front of each covariate in the formula.
For example, if the data frame is called DataFrame you
-avoid having to write: \(DataFrame$y ~ DataFrame$a + DataFrame$b + DataFrame$c + DataFrame$d\)
+avoid having to write: \(DataFrame\$y ~ DataFrame\$a + DataFrame\$b + DataFrame\$c + DataFrame\$d\)
The checks argument verifies that the variables in the model are all defined (exist)
on the server-site at every study
and that they have the correct characteristics required to fit the model.
@@ -493,11 +493,11 @@
In formula most shortcut notation allowed by glmer() function is
also allowed by ds.glmerSLMA.
Many GLMEs can be fitted very simply using a formula like:
-$$y~a+b+(1|c)$$
+\(y~a+b+(1|c)\)
which simply means fit an GLME with y as the outcome variable (e.g.
a binary case-control using a logistic regression model or a count or a survival
time using a Poisson regression model), a and b
as fixed effects, and c as a random effect or grouping factor.
It is also possible to fit models with random slopes by specifying a model such as
-$$y~a+b+(1+b|c)$$
+\(y~a+b+(1+b|c)\)
where the effect of b can vary randomly between groups defined by c.
Implicit nesting can be specified with formulas such as: \(y~a+b+(1|c/d)\)
or \(y~a+b+(1|c)+(1|c:d)\).
@@ -249,7 +249,7 @@
Details
The dataName argument avoids you having to specify the name of the
data frame in front of each covariate in the formula.
For example, if the data frame is called DataFrame you avoid having to write:
-\(DataFrame$y ~ DataFrame$a + DataFrame$b + (1 | DataFrame$c)\).
The checks argument verifies that the variables in the model are all defined (exist)
on the server-site at every study
and that they have the correct characteristics required to fit the model.
@@ -379,11 +379,11 @@
obtained using R help for lmer and the lme4 package.
In formula most shortcut notation allowed by lmer() function is
also allowed by ds.lmerSLMA. Many LMEs can be fitted very simply using a formula like:
-$$y ~ a + b + (1 | c)$$
+\(y ~ a + b + (1 | c)\)
which simply means fit an LME with y as the outcome variable with a and b
as fixed effects, and c as a random effect or grouping factor.
It is also possible to fit models with random slopes by specifying a model such as
-$$y ~ a + b + (1 + b | c)$$
+\(y ~ a + b + (1 + b | c)\)
where the effect of b can vary randomly between groups defined by c.
Implicit nesting can be specified with formulae such as \(y ~ a + b + (1 | c / d)\)
or \(y ~ a + b + (1 | c) + (1 | c : d)\).
The dataName argument avoids you having to specify the name of the
data frame in front of each covariate in the formula.
For example, if the data frame is called DataFrame you avoid having to write:
-\(DataFrame$y ~ DataFrame$a + DataFrame$b + (1 | DataFrame$c)\).
The checks argument verifies that the variables in the model are all defined (exist)
on the server-site at every study
and that they have the correct characteristics required to fit the model.
@@ -328,11 +328,11 @@
diff --git a/dsBase_6.3.1-permissive.tar.gz b/dsBase_6.3.2-permissive.tar.gz
similarity index 53%
rename from dsBase_6.3.1-permissive.tar.gz
rename to dsBase_6.3.2-permissive.tar.gz
index 4acec10b7..0d70f01c6 100644
Binary files a/dsBase_6.3.1-permissive.tar.gz and b/dsBase_6.3.2-permissive.tar.gz differ
diff --git a/dsBase_6.3.1.tar.gz b/dsBase_6.3.2.tar.gz
similarity index 50%
rename from dsBase_6.3.1.tar.gz
rename to dsBase_6.3.2.tar.gz
index 042b8a372..5d93ba950 100644
Binary files a/dsBase_6.3.1.tar.gz and b/dsBase_6.3.2.tar.gz differ
diff --git a/man/ds.glm.Rd b/man/ds.glm.Rd
index 4746ce2c7..67728e009 100644
--- a/man/ds.glm.Rd
+++ b/man/ds.glm.Rd
@@ -138,7 +138,7 @@ function is also allowed by \code{ds.glm}.
Many GLMs can be fitted very simply using a formula such as:
-\deqn{y~a+b+c+d}
+\eqn{y~a+b+c+d}
which simply means fit a GLM with \code{y} as the outcome variable and
\code{a}, \code{b}, \code{c} and \code{d} as covariates.
@@ -147,7 +147,7 @@ By default all such models also include an intercept (regression constant) term.
Instead, if you need to fit a more complex
model, for example:
- \deqn{EVENT~1+TID+SEXF*AGE.60}
+ \eqn{EVENT~1+TID+SEXF*AGE.60}
In the above model the outcome variable is \code{EVENT}
and the covariates
diff --git a/man/ds.glmSLMA.Rd b/man/ds.glmSLMA.Rd
index f2e7fdefb..f0a9863d4 100644
--- a/man/ds.glmSLMA.Rd
+++ b/man/ds.glmSLMA.Rd
@@ -241,7 +241,7 @@ function is also allowed by \code{ds.glmSLMA}.
Many glms can be fitted very simply using a formula such as:
-\deqn{y~a+b+c+d}
+\eqn{y~a+b+c+d}
which simply means fit a glm with \code{y} as the outcome variable and
\code{a}, \code{b}, \code{c} and \code{d} as covariates.
@@ -250,7 +250,7 @@ By default all such models also include an intercept (regression constant) term.
Instead, if you need to fit a more complex
model, for example:
- \deqn{EVENT~1+TID+SEXF*AGE.60}
+\eqn{EVENT~1+TID+SEXF*AGE.60}
In the above model the outcome variable is \code{EVENT}
and the covariates
diff --git a/man/ds.glmerSLMA.Rd b/man/ds.glmerSLMA.Rd
index 19d5a55ad..8ad49c3ae 100644
--- a/man/ds.glmerSLMA.Rd
+++ b/man/ds.glmerSLMA.Rd
@@ -169,17 +169,17 @@ If it did not some information about the reason for this is reported.
In \code{formula} most shortcut notation allowed by \code{glmer()} function is
also allowed by \code{ds.glmerSLMA}.
Many GLMEs can be fitted very simply using a formula like:
-\deqn{y~a+b+(1|c)}
+\eqn{y~a+b+(1|c)}
which simply means fit an GLME with \code{y} as the outcome variable (e.g.
a binary case-control using a logistic regression model or a count or a survival
time using a Poisson regression model), \code{a} and \code{b}
as fixed effects, and \code{c} as a random effect or grouping factor.
It is also possible to fit models with random slopes by specifying a model such as
-\deqn{y~a+b+(1+b|c)}
+\eqn{y~a+b+(1+b|c)}
where the effect of \code{b} can vary randomly between groups defined by \code{c}.
Implicit nesting can be specified with formulas such as: \eqn{y~a+b+(1|c/d)}
-or \eqn{y~a+b+(1|c)+(1|c:d)}.
+or \eqn{y~a+b+(1|c)+(1|c:d)}.
The \code{dataName} argument avoids you having to specify the name of the
diff --git a/man/ds.lmerSLMA.Rd b/man/ds.lmerSLMA.Rd
index 3ea75c10a..dbd9b7fbe 100644
--- a/man/ds.lmerSLMA.Rd
+++ b/man/ds.lmerSLMA.Rd
@@ -168,12 +168,12 @@ obtained using R help for \code{lmer} and the \code{lme4} package.
In \code{formula} most shortcut notation allowed by \code{lmer()} function is
also allowed by \code{ds.lmerSLMA}. Many LMEs can be fitted very simply using a formula like:
-\deqn{y ~ a + b + (1 | c)}
+\eqn{y ~ a + b + (1 | c)}
which simply means fit an LME with \code{y} as the outcome variable with \code{a} and \code{b}
as fixed effects, and \code{c} as a random effect or grouping factor.
It is also possible to fit models with random slopes by specifying a model such as
-\deqn{y ~ a + b + (1 + b | c)}
+\eqn{y ~ a + b + (1 + b | c)}
where the effect of \code{b} can vary randomly between groups defined by \code{c}.
Implicit nesting can be specified with formulae such as \eqn{y ~ a + b + (1 | c / d)}
or \eqn{y ~ a + b + (1 | c) + (1 | c : d)}.
diff --git a/opal_azure-pipelines.yml b/opal_azure-pipelines.yml
index 06fdade52..684052d9f 100644
--- a/opal_azure-pipelines.yml
+++ b/opal_azure-pipelines.yml
@@ -58,10 +58,10 @@ schedules:
- master
always: true
- cron: "0 2 * * *"
- displayName: Nightly build - v6.3.1-dev
+ displayName: Nightly build - v6.3.2-dev
branches:
include:
- - v6.3.1-dev
+ - v6.3.2-dev
always: true
#########################################################################################
@@ -132,7 +132,7 @@ jobs:
sudo apt-get upgrade -y
sudo apt-get install -qq libxml2-dev libcurl4-openssl-dev libssl-dev libgsl-dev libgit2-dev r-base -y
- sudo apt-get install -qq libharfbuzz-dev libfribidi-dev libmagick++-dev -y
+ sudo apt-get install -qq libharfbuzz-dev libfribidi-dev libmagick++-dev libudunits2-dev -y
sudo R -q -e "install.packages(c('curl','httr'), dependencies=TRUE, repos='https://cloud.r-project.org')"
sudo R -q -e "install.packages(c('devtools','covr'), dependencies=TRUE, repos='https://cloud.r-project.org')"
sudo R -q -e "install.packages(c('fields','meta','metafor','ggplot2','gridExtra','data.table','panelaggregation'), dependencies=TRUE, repos='https://cloud.r-project.org')"
@@ -186,7 +186,7 @@ jobs:
# If this step fails still mark as failed, but don't stop the rest of the steps running.
- bash: |
- R -q -e "library('devtools'); devtools::check(args = c('--no-examples'))" | tee azure-pipelines_check.Rout
+ R -q -e "library('devtools'); devtools::check(args = c('--no-examples', '--no-tests'))" | tee azure-pipelines_check.Rout
grep --quiet "^0 errors" azure-pipelines_check.Rout && grep --quiet " 0 warnings" azure-pipelines_check.Rout && grep --quiet " 0 notes" azure-pipelines_check.Rout
workingDirectory: $(Pipeline.Workspace)/dsBaseClient
@@ -235,7 +235,7 @@ jobs:
- bash: |
R -q -e "library(opalr); opal <- opal.login(username = 'administrator', password = 'datashield_test&', url = 'https://localhost:8443', opts = list(ssl_verifyhost=0, ssl_verifypeer=0)); opal.put(opal, 'system', 'conf', 'general', '_rPackage'); opal.logout(o)"
- R -q -e "library(opalr); opal <- opal.login('administrator','datashield_test&', url='https://localhost:8443/', opts = list(ssl_verifyhost=0, ssl_verifypeer=0)); dsadmin.install_github_package(opal, 'dsBase', username = 'datashield', ref = '6.3.1'); opal.logout(opal)"
+ R -q -e "library(opalr); opal <- opal.login('administrator','datashield_test&', url='https://localhost:8443/', opts = list(ssl_verifyhost=0, ssl_verifypeer=0)); dsadmin.install_github_package(opal, 'dsBase', username = 'datashield', ref = '6.3.2'); opal.logout(opal)"
sleep 60
@@ -261,7 +261,7 @@ jobs:
# best guess is that there is an implicit build or similar that happens. Although
# I cannot replicate that directly with build etc directly.
- sudo R --verbose -e 'devtools::check()'
+ sudo R --verbose -e 'devtools::reload()'
mkdir $(Pipeline.Workspace)/logs
@@ -379,9 +379,8 @@ jobs:
- bash: |
# See, 'Code coverage and JUnit report output' for issues with the approach and improvement needed.
- sudo R --verbose -e 'devtools::check()'
+ sudo R --verbose -e 'devtools::reload()'
- pwd
mkdir $(Pipeline.Workspace)/logs
# run the coverage tool and output to coveragelist.csv
diff --git a/tests/docker/armadillo/standard/config/application.yml b/tests/docker/armadillo/standard/config/application.yml
index c38ba2795..87e0fa1fb 100644
--- a/tests/docker/armadillo/standard/config/application.yml
+++ b/tests/docker/armadillo/standard/config/application.yml
@@ -14,11 +14,13 @@ armadillo:
# oidc-admin-user: user@yourdomain.org
profiles:
- name: default
- image: datashield/rock-knot-devel-permissive:latest
+ image: datashield/rock-lemon-donkey-permissive:latest
port: 8085
host: default
- package-whitelist:
+ package-whitelist: # Packages for 'donkey'
- dsBase
+ - dsSurvival
+ - dsTidyverse
- resourcer
function-blacklist: [ ]
options:
diff --git a/tests/testthat.R b/tests/testthat.R
new file mode 100644
index 000000000..3e6bbe151
--- /dev/null
+++ b/tests/testthat.R
@@ -0,0 +1,12 @@
+# This file is part of the standard setup for testthat.
+# It is recommended that you do not modify it.
+#
+# Where should you do additional test configuration?
+# Learn more about the roles of various files in:
+# * https://r-pkgs.org/testing-design.html#sec-tests-files-overview
+# * https://testthat.r-lib.org/articles/special-files.html
+
+library(testthat)
+library(dsBaseClient)
+
+test_check("dsBaseClient")
diff --git a/tests/testthat/perf_files/armadillo_azure-pipeline.csv b/tests/testthat/perf_files/armadillo_azure-pipeline.csv
index 5fd247c97..186e1d583 100644
--- a/tests/testthat/perf_files/armadillo_azure-pipeline.csv
+++ b/tests/testthat/perf_files/armadillo_azure-pipeline.csv
@@ -1,14 +1,14 @@
"refer_name","rate","lower_tolerance","upper_tolerance"
-"conndisconn::perf::simple0","0.1050","0.5","2"
-"ds.abs::perf::0","3.896","0.5","2"
-"ds.asInteger::perf:0","3.550","0.5","2"
-"ds.asList::perf:0","8.040","0.5","2"
-"ds.asNumeric::perf:0","3.577","0.5","2"
-"ds.assign::perf::0","6.739","0.5","2"
-"ds.class::perf::combine:0","8.171","0.5","2"
-"ds.colnames::perf:0","6.292","0.5","2"
-"ds.exists::perf::combine:0","16.33","0.5","2"
-"ds.length::perf::combine:0","16.08","0.5","2"
-"ds.mean::perf::combine:0","16.08","0.5","2"
-"ds.mean::perf::split:0","15.83","0.5","2"
-"void::perf::void::0","36510.0","0.5","2"
+"conndisconn::perf::simple0","0.1275","0.5","2"
+"ds.abs::perf::0","4.824","0.5","2"
+"ds.asInteger::perf:0","4.366","0.5","2"
+"ds.asList::perf:0","9.787","0.5","2"
+"ds.asNumeric::perf:0","4.316","0.5","2"
+"ds.assign::perf::0","8.055","0.5","2"
+"ds.class::perf::combine:0","9.847","0.5","2"
+"ds.colnames::perf:0","7.574","0.5","2"
+"ds.exists::perf::combine:0","19.84","0.5","2"
+"ds.length::perf::combine:0","19.58","0.5","2"
+"ds.mean::perf::combine:0","19.66","0.5","2"
+"ds.mean::perf::split:0","19.21","0.5","2"
+"void::perf::void::0","41810.0","0.5","2"
diff --git a/tests/testthat/perf_files/default_perf_profile.csv b/tests/testthat/perf_files/default_perf_profile.csv
index 9d5c755f1..cff242360 100644
--- a/tests/testthat/perf_files/default_perf_profile.csv
+++ b/tests/testthat/perf_files/default_perf_profile.csv
@@ -1,14 +1,14 @@
"refer_name","rate","lower_tolerance","upper_tolerance"
-"conndisconn::perf::simple0","0.229","0.5","2"
-"ds.abs::perf::0","1.796","0.5","2"
-"ds.asInteger::perf:0","1.538","0.5","2"
-"ds.asList::perf:0","3.061","0.5","2"
-"ds.asNumeric::perf:0","1.548","0.5","2"
-"ds.assign::perf::0","3.556","0.5","2"
-"ds.class::perf::combine:0","3.149","0.5","2"
-"ds.colnames::perf:0","2.584","0.5","2"
-"ds.exists::perf::combine:0","7.138","0.5","2"
-"ds.length::perf::combine:0","6.385","0.5","2"
-"ds.mean::perf::combine:0","5.982","0.5","2"
-"ds.mean::perf::split:0","6.923","0.5","2"
-"void::perf::void::0","41810.0","0.5","2"
+"conndisconn::perf::simple0","0.2118","0.5","2"
+"ds.abs::perf::0","1.718","0.5","2"
+"ds.asInteger::perf:0","1.484","0.5","2"
+"ds.asList::perf:0","3.050","0.5","2"
+"ds.asNumeric::perf:0","1.508","0.5","2"
+"ds.assign::perf::0","3.547","0.5","2"
+"ds.class::perf::combine:0","3.061","0.5","2"
+"ds.colnames::perf:0","2.456","0.5","2"
+"ds.exists::perf::combine:0","6.904","0.5","2"
+"ds.length::perf::combine:0","6.058","0.5","2"
+"ds.mean::perf::combine:0","5.892","0.5","2"
+"ds.mean::perf::split:0","6.881","0.5","2"
+"void::perf::void::0","27070.0","0.5","2"
diff --git a/tests/testthat/perf_files/dslite_hp-laptop_quay.csv b/tests/testthat/perf_files/dslite_hp-laptop_quay.csv
new file mode 100644
index 000000000..5d552ae05
--- /dev/null
+++ b/tests/testthat/perf_files/dslite_hp-laptop_quay.csv
@@ -0,0 +1,14 @@
+"refer_name","rate","lower_tolerance","upper_tolerance"
+"conndisconn::perf::simple0","1.28701068653782","0.5","2"
+"ds.abs::perf::0","9.58736733800142","0.5","2"
+"ds.asInteger::perf:0","8.50891366904172","0.5","2"
+"ds.asList::perf:0","16.5820946915488","0.5","2"
+"ds.asNumeric::perf:0","9.11018116242571","0.5","2"
+"ds.assign::perf::0","20.7627800741047","0.5","2"
+"ds.class::perf::combine:0","16.4968034024194","0.5","2"
+"ds.colnames::perf:0","12.2919611789594","0.5","2"
+"ds.exists::perf::combine:0","41.3622556042039","0.5","2"
+"ds.length::perf::combine:0","41.0818690662793","0.5","2"
+"ds.mean::perf::combine:0","40.9888639028757","0.5","2"
+"ds.mean::perf::split:0","41.2851424288384","0.5","2"
+"void::perf::void::0","24346.5613457168","0.5","2"
diff --git a/tests/testthat/perf_files/opal_azure-pipeline.csv b/tests/testthat/perf_files/opal_azure-pipeline.csv
index 9d5c755f1..cff242360 100644
--- a/tests/testthat/perf_files/opal_azure-pipeline.csv
+++ b/tests/testthat/perf_files/opal_azure-pipeline.csv
@@ -1,14 +1,14 @@
"refer_name","rate","lower_tolerance","upper_tolerance"
-"conndisconn::perf::simple0","0.229","0.5","2"
-"ds.abs::perf::0","1.796","0.5","2"
-"ds.asInteger::perf:0","1.538","0.5","2"
-"ds.asList::perf:0","3.061","0.5","2"
-"ds.asNumeric::perf:0","1.548","0.5","2"
-"ds.assign::perf::0","3.556","0.5","2"
-"ds.class::perf::combine:0","3.149","0.5","2"
-"ds.colnames::perf:0","2.584","0.5","2"
-"ds.exists::perf::combine:0","7.138","0.5","2"
-"ds.length::perf::combine:0","6.385","0.5","2"
-"ds.mean::perf::combine:0","5.982","0.5","2"
-"ds.mean::perf::split:0","6.923","0.5","2"
-"void::perf::void::0","41810.0","0.5","2"
+"conndisconn::perf::simple0","0.2118","0.5","2"
+"ds.abs::perf::0","1.718","0.5","2"
+"ds.asInteger::perf:0","1.484","0.5","2"
+"ds.asList::perf:0","3.050","0.5","2"
+"ds.asNumeric::perf:0","1.508","0.5","2"
+"ds.assign::perf::0","3.547","0.5","2"
+"ds.class::perf::combine:0","3.061","0.5","2"
+"ds.colnames::perf:0","2.456","0.5","2"
+"ds.exists::perf::combine:0","6.904","0.5","2"
+"ds.length::perf::combine:0","6.058","0.5","2"
+"ds.mean::perf::combine:0","5.892","0.5","2"
+"ds.mean::perf::split:0","6.881","0.5","2"
+"void::perf::void::0","27070.0","0.5","2"
diff --git a/tests/testthat/perf_files/opal_hp-laptop_quay.csv b/tests/testthat/perf_files/opal_hp-laptop_quay.csv
index da068a01d..a6e5e655a 100644
--- a/tests/testthat/perf_files/opal_hp-laptop_quay.csv
+++ b/tests/testthat/perf_files/opal_hp-laptop_quay.csv
@@ -1,14 +1,14 @@
"refer_name","rate","lower_tolerance","upper_tolerance"
-"conndisconn::perf::simple0","0.145258829974366","0.5","2"
-"ds.abs::perf::0","0.685354162883962","0.5","2"
-"ds.asInteger::perf:0","0.757343916339244","0.5","2"
-"ds.asList::perf:0","1.39411478465579","0.5","2"
-"ds.asNumeric::perf:0","0.695929483688074","0.5","2"
-"ds.assign::perf::0","1.98579096107968","0.5","2"
-"ds.class::perf::combine:0","1.83959664387857","0.5","2"
-"ds.colnames::perf:0","1.38390626627527","0.5","2"
-"ds.exists::perf::combine:0","4.37111331491725","0.5","2"
-"ds.length::perf::combine:0","2.99769707214692","0.5","2"
-"ds.mean::perf::combine:0","3.14458208946095","0.5","2"
-"ds.mean::perf::split:0","4.258064355457","0.5","2"
-"void::perf::void::0","20588.7831697084","0.5","2"
+"conndisconn::perf::simple0","0.163258942292474","0.5","2"
+"ds.abs::perf::0","0.855013692368105","0.5","2"
+"ds.asInteger::perf:0","0.788986058823576","0.5","2"
+"ds.asList::perf:0","1.77505549252221","0.5","2"
+"ds.asNumeric::perf:0","0.877591207737289","0.5","2"
+"ds.assign::perf::0","2.08707546713196","0.5","2"
+"ds.class::perf::combine:0","1.65635603819885","0.5","2"
+"ds.colnames::perf:0","1.33221754701434","0.5","2"
+"ds.exists::perf::combine:0","4.18346517297051","0.5","2"
+"ds.length::perf::combine:0","3.45700158311582","0.5","2"
+"ds.mean::perf::combine:0","3.36796688580702","0.5","2"
+"ds.mean::perf::split:0","4.11472547478384","0.5","2"
+"void::perf::void::0","23198.7075219865","0.5","2"
diff --git a/tests/testthat/perf_files/template_perf_profile.csv b/tests/testthat/perf_files/template_perf_profile.csv
new file mode 100644
index 000000000..c01b6fec1
--- /dev/null
+++ b/tests/testthat/perf_files/template_perf_profile.csv
@@ -0,0 +1 @@
+"refer_name","rate","lower_tolerance","upper_tolerance"
diff --git a/tests/testthat/perf_tests/perf_rate.R b/tests/testthat/perf_tests/perf_rate.R
index 1884cda89..0384bf637 100644
--- a/tests/testthat/perf_tests/perf_rate.R
+++ b/tests/testthat/perf_tests/perf_rate.R
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2024 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
+# Copyright (c) 2024-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved.
#
# This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0.
@@ -47,4 +47,3 @@ perf.reference.tolerance.upper <- function(perf.ref.name) {
return(as.numeric(.perf.reference[which(.perf.reference$refer_name == perf.ref.name),]$upper_tolerance))
}
-