Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #41

Merged
merged 8 commits into from
May 28, 2020
Merged

Dev #41

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
authors = ["Vladimir Arnautov (mail@pharmcat.net)"]
name = "ClinicalTrialUtilities"
uuid = "535c2557-d7d0-564d-8ff9-4ae146c18cfe"
version = "0.2.5"
version = "0.2.6"

[deps]
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Expand All @@ -24,13 +24,13 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
test = ["CSV", "Test", "Plots"]

[compat]
julia = "1.0, 1.1, 1.2, 1.3"
julia = "1.0, 1.1, 1.2, 1.3, 1.4"
Distributions = "0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23"
StatsBase = "0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33"
DataFrames = "0.19, 0.20"
QuadGK = "2.0, 2.1, 2.2, 2.3"
SpecialFunctions = "0.8, 0.9, 0.10"
Roots = "0.7, 0.8, 1.0"
CSV = "0.5"
RecipesBase = "0.7, 0.8"
CSV = "0.5, 0.6"
RecipesBase = "0.7, 0.8, 1.0"
Reexport = "0.1, 0.2"
50 changes: 45 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ClinicalTrialUtilities

Clinical trial related calculation: descriptive statistics, power and sample size calculation, power simulations, confidence interval, pharmacokinetics/pharmacodynamics parameters calculation.
Clinical trial related calculation: descriptive statistics, power and sample size calculation, power simulations, confidence interval, pharmacokinetics/pharmacodynamics parameters calculation. This program comes with absolutely no warranty. No liability is accepted for any loss and risk to public health resulting from use of this software.

[![Build Status](https://travis-ci.com/PharmCat/ClinicalTrialUtilities.jl.svg?branch=master)](https://travis-ci.com/PharmCat/ClinicalTrialUtilities.jl)
[![Build status](https://ci.appveyor.com/api/projects/status/35f8b5vq259sbssg?svg=true)](https://ci.appveyor.com/project/PharmCat/clinicaltrialutilities-jl)
Expand All @@ -17,17 +17,26 @@ The package is designed to perform calculations related to the planning and anal
using Pkg; Pkg.add("ClinicalTrialUtilities");
```

### <a name="Usage">Usage</a>
### <a name="Features">Main features</a>

- Clinical trial sample size calculation
- Power calculation
- Confidence Interval calculation
- NCA Pharmacokinetics parameters calculation
- Descriptive statistics and frequencies
- Randomization


### <a name="Examples">Examples</a>

#### SampleSize

**NB! Hypothesis types:**

- :ea - Equality: two-sided;
- :ei - Equivalencens: two one-sided hypothesis;
- :ns - Non-Inferiority / Superiority: one-sided hypothesis, for some cases you should use two-sided hypothesis for Non-Inferiority/Superiority, you can use alpha/2 for this;

### <a name="Examples">Examples</a>

#### SampleSize
```
#Sample size for one proportion equality
ctsamplen(param=:prop, type=:ea, group=:one, a=0.3, b=0.5)
Expand Down Expand Up @@ -93,6 +102,37 @@ pooledcv([0.12, 0.2, 0.25], [14, 22, 32], [:d2x2, :d2x2, :d2x2])

```

#### Confidence Intervals
```
using ClinicalTrialUtilities
ci = propci(38, 100, alpha=0.05, method=:cp)

ci = orpropci(30, 100, 40, 90; alpha=0.05, method=:mn)

ci = diffpropci(30, 100, 40, 90; alpha=0.05, method=:wald)

ci = meanci(30, 10, 30, alpha = 0.05, method=:norm)
```

#### NCA
```
using CSV, DataFrames, ClinicalTrialUtilities
pkdata2 = CSV.File("pkdata.csv") |> DataFrame
pkds = pkimport(pkdata2, [:Subject, :Formulation]; time = :Time, conc = :Concentration)
pk = nca!(pkds)
ncadf = DataFrame(pk; unst = true)
ds = ClinicalTrialUtilities.descriptive(ncadf, stats = [:n, :mean, :sd], sort = [:Formulation])
dsdf = ClinicalTrialUtilities.DataFrame(ds; unst = true)

```

#### Randomization
```
using DataFrames, ClinicalTrialUtilities
rt = ClinicalTrialUtilities.randomtable(;blocksize = 4, subject = 32, group = 2, ratio = [1,1], grseq = ["TR", "RT"], seed = 36434654652452)
```


### <a name="Copyrights">Copyrights</a>

Clinical Trial Utilities
Expand Down
14 changes: 14 additions & 0 deletions cange.log
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
v0.2.6

- findfirst
- Documents update
- export applyncarule!
- code cleaning
- improve coverage
- plots kwargs
- Proportion meta-analysis
- Tests restruct
- Hypothesis test for simulation
- Deps update
- Docs

v0.2.5

- SpecialFunctions 0.10
Expand Down
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ makedocs(
"Descriptive statistics" => "ds.md",
"NCA" => ["NCA" => "nca.md",
"Pharmakokinetics" => "pk.md",
"Pharmacodynamics" => "pd.md"],
"Pharmacodynamics" => "pd.md",
"PK Plots" => "pkplot.md"],
"Randomization" => "random.md",
"Simulations" => "sim.md",
"Utilities" => "utils.md",
Expand Down
15 changes: 15 additions & 0 deletions docs/src/ds.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,18 @@ Calculation descriptive statistics by groups.
```@docs
ClinicalTrialUtilities.descriptive
```

### freque
```@docs
ClinicalTrialUtilities.freque
```

### contab
```@docs
ClinicalTrialUtilities.contab
```

### metaprop
```@docs
ClinicalTrialUtilities.metaprop
```
6 changes: 6 additions & 0 deletions docs/src/pkplot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
### PK plots

#### pkplot
```@docs
ClinicalTrialUtilities.pkplot
```
24 changes: 12 additions & 12 deletions src/ClinicalTrialUtilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,9 @@ using Distributions, Random, Roots, QuadGK, RecipesBase, Reexport
@reexport using StatsBase

import SpecialFunctions
import Base.show
import Base.showerror
import Base.getindex
import Base.length
import Base.in
import Base.iterate
import Base.eltype
import Base: show, findfirst, getproperty, showerror, getindex, length, in, iterate, eltype, deleteat!, findall
import StatsBase.confint
import DataFrames: DataFrame, DataFrames, names!, unstack, deleterows!
import DataFrames: DataFrame, DataFrames, names!, unstack, deleterows!, rename!

function lgamma(x)
return SpecialFunctions.logabsgamma(x)[1]
Expand All @@ -42,10 +36,15 @@ const PI2INV = 0.5 / π
include("abstracttypes.jl")

include("design.jl")
include("hypothesis.jl")

include("proportion.jl")

include("means.jl")

#Confidence interval calculation
include("ci.jl")

include("hypothesis.jl")

#Owen function calc: owensQ, owensQo, ifun1, owensTint2, owensT, tfn
include("owensq.jl")
Expand All @@ -55,8 +54,6 @@ include("powertost.jl")
include("powersamplesize.jl")
#Main sample size and power functions: sampleSize, ctpower, besamplen
include("samplesize.jl")
#Confidence interval calculation
include("ci.jl")
#Simulations
include("sim.jl")
#info function
Expand Down Expand Up @@ -101,6 +98,7 @@ pooledcv,
descriptive,
freque,
contab,
metaprop,
htmlexport,
#CI
confint,
Expand All @@ -124,11 +122,13 @@ DataFrame,
ElimRange,
DoseTime,
LimitRule,
applyncarule!,
keldata,
# Simulation
ctsim,
#Plots
plot
pkplot,
pkplot!



Expand Down
15 changes: 13 additions & 2 deletions src/ci.jl
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ function diffmcnmwaldci(a::Int, b::Int, c::Int, d::Int; alpha = 0.05)
p1 = (a + b)/n
p2 = (a + c)/n
estimate = p1 - p2
se = ((a+d)*(b+c)+4*b*c)/n^3
se = sqrt(((a+d)*(b+c)+4*b*c)/n^3)
z = quantile(ZDIST, 1 - alpha / 2)
ConfInt(estimate - z * se, estimate + z * se, estimate , alpha)
end
Expand All @@ -889,8 +889,19 @@ function diffmcnmwaldccci(a::Int, b::Int, c::Int, d::Int; alpha = 0.05)
p1 = (a + b)/n
p2 = (a + c)/n
estimate = p1 - p2
se = ((a+d)*(b+c)+4*b*c)/n^3
se = sqrt(((a+d)*(b+c)+4*b*c)/n^3)
z = quantile(ZDIST, 1 - alpha / 2)
ConfInt(estimate - z * se - 1 / n, estimate + z * se + 1 / n, estimate , alpha)
end

#=
function diffmcnmci(a::Int, b::Int, c::Int, d::Int; alpha = 0.05)
n = a + b + c + d
p1 = (a + b)/n
p2 = (a + c)/n
estimate = p1 - p2
se = sqrt((p1 * (1 - p1) + p2 * (1 - p2) - 2 * (a * d - b * c) / n^2) / n)
z = quantile(ZDIST, 1 - alpha / 2)
ConfInt(estimate - z * se, estimate + z * se, estimate , alpha)
end
=#
69 changes: 69 additions & 0 deletions src/dataset.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,81 @@
struct DataSet{T <: AbstractData}
data::Vector{T}
end

#!!!
function in(a::Dict, b::Dict)
k = collect(keys(a))
if any(x -> x ∉ collect(keys(b)), k) return false end
for i = 1:length(a)
if a[k[i]] != b[k[i]] return false end
end
return true
end
function in(a::Pair, b::Dict)
if a[1] ∉ collect(keys(b)) return false end
if a[2] != b[a[1]] return false end
return true
end

#length
function Base.length(a::DataSet)::Int
return length(a.data)
end
#Iterate
function Base.iterate(iter::DataSet)
return Base.iterate(iter.data)
end
function Base.iterate(iter::DataSet, i::Int)
return Base.iterate(iter.data, i)
end
#Eltype
function Base.eltype(obj::DataSet)
return eltype(obj.data)
end
#Getindex
function Base.getindex(a::DataSet{T}, i::Int)::T where T
return a.data[i]
end
function Base.getindex(a::DataSet{T}, d::Pair)::T where T
for i = 1:length(a)
if d ∈ a[i].sort return a[i] end
end
throw(ArgumentError("Element not found!"))
end
function Base.getindex(a::DataSet{T}, d::Dict)::T where T
for i = 1:length(a)
if d ∈ a[i].sort return a[i] end
end
throw(ArgumentError("Element not found!"))
end
function Base.getindex(a::DataSet{T}, d::Tuple{Vararg{Pair}})::T where T
return a[Dict(d)]
end


function Base.getindex(a::DataSet{T}, i::Int, s::Symbol)::Real where T
return a.data[i].result[s]
end
#
function Base.findall(a::DataSet{T}, sort::Dict) where T
inds = Vector{Int}(undef, 0)
for i = 1:length(a)
if sort ∈ a.data[i].sort push!(inds, i) end
end
inds
end
#
function Base.deleteat!(a::DataSet{T}, i::Int) where T
deleteat!(a.data, i)
return a
end

function Base.deleteat!(a::DataSet{T}, inds::AbstractArray) where T
deleteat!(a.data, inds)
return a
end

function Base.deleteat!(a::DataSet{T}, inds::Dict) where T
deleteat!(a.data, findall(a, inds))
return a
end
24 changes: 0 additions & 24 deletions src/descriptives.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,6 @@ function Base.show(io::IO, obj::DataSet{Descriptive})
println(io, "____________________")
end
end
function Base.getindex(a::DataSet{T}, i::Int)::T where T
return a.data[i]
end
function Base.getindex(a::DataSet{T}, i::Int, s::Symbol)::Real where T
return a.data[i].result[s]
end
function Base.getindex(a::DataSet{T}, d::Pair)::T where T
for i = 1:length(a)
if d ∈ a[i].sort return a[i] end
end
throw(ArgumentError("Element not found!"))
end
function Base.getindex(a::DataSet{T}, d::Dict)::T where T
for i = 1:length(a)
if d ∈ a[i].sort return a[i] end
end
throw(ArgumentError("Element not found!"))
end
function Base.getindex(a::DataSet{T}, d::Tuple{Vararg{Pair}})::T where T
return a[Dict(d)]
end
function Base.length(a::DataSet{T})::Int where T <: AbstractData
return length(a.data)
end
"""
descriptive(data::DataFrame;
sort::Union{Symbol, Array{T,1}} = Array{Symbol,1}(undef,0),
Expand Down
Loading