From b4dfa3af70fdab35633c00103d360b173ff279e7 Mon Sep 17 00:00:00 2001 From: PharmCat Date: Thu, 12 Nov 2020 22:44:51 +0300 Subject: [PATCH 1/3] doc update --- src/ci.jl | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/ci.jl b/src/ci.jl index 7067f4e..ffa2e00 100644 --- a/src/ci.jl +++ b/src/ci.jl @@ -162,13 +162,25 @@ Confidence interval for proportion difference. # Computation methods: -- :nhs - Newcombes Hybrid (wilson) Score interval for the difference of proportions; -- :nhscc - Newcombes Hybrid Score CC; -- :ac - Agresti-Caffo interval for the difference of proportions; -- :mn | :default - Method of Mee 1984 with Miettinen and Nurminen modification; -- :mee | :fm - Mee maximum likelihood method; -- :wald - Wald CI without CC; -- :waldcc - Wald CI with CC; +- `:nhs` - Newcombes Hybrid (wilson) Score interval for the difference of proportions; +- `:nhscc` - Newcombes Hybrid Score CC; +- `:ac` - Agresti-Caffo interval for the difference of proportions; +- `:mn` | `:default` - Method of Mee 1984 with Miettinen and Nurminen modification; +- `:mee` | `:fm` - Mee maximum likelihood method; +- `:wald` - Wald CI without CC; +- `:waldcc` - Wald CI with CC; + +# References + + * nhs, nhscc - Newcombe RG (1998), Interval Estimation for the Difference Between Independent Proportions: Comparison of Eleven Methods. Statistics in Medicine 17, 873-890. + * ac - Agresti A, Caffo B., “Simple and effective confidence intervals for proportions and differences of proportions result from adding two successes and two failures”, American Statistician 54: 280–288 (2000) + * mn - Miettinen, O. and Nurminen, M. (1985), Comparative analysis of two rates. Statist. Med., 4: 213-226. doi:10.1002/sim.4780040211 + * mee - Mee RW (1984) Confidence bounds for the difference between two probabilities, Biometrics40:1175-1176 + * Brown, L.D., Cai, T.T., and DasGupta, A. Interval estimation for a binomial proportion. + Statistical Science, 16(2):101–117, 2001. + * Farrington, C. P. and Manning, G. (1990), “Test Statistics and Sample Size Formulae for Comparative Binomial Trials with Null Hypothesis of Non-zero Risk Difference or Non-unity Relative Risk,” Statistics in Medicine, 9, 1447–1454 + * Li HQ, Tang ML, Wong WK. Confidence intervals for ratio of two Poisson rates using the methodof variance estimates recovery. Computational Statistics 2014; 29(3-4):869-889 + * Brown, L., Cai, T., & DasGupta, A. (2003). INTERVAL ESTIMATION IN EXPONENTIAL FAMILIES. Statistica Sinica, 13(1), 19-49. """ function diffpropci(x1::Int, n1::Int, x2::Int, n2::Int; alpha::Real = 0.05, method::Symbol = :default)::ConfInt if alpha >= 1.0 || alpha <= 0.0 From 32c9e8ee2428ef847bd62446a3bbf0592c505c94 Mon Sep 17 00:00:00 2001 From: PharmCat Date: Thu, 19 Nov 2020 01:52:42 +0300 Subject: [PATCH 2/3] update --- Project.toml | 2 +- cange.log | 5 +++++ src/ci.jl | 12 ++++++++++++ src/freque.jl | 9 ++++++--- src/show.jl | 18 ++++++++++++++++++ test/freque.jl | 4 ++++ test/test.jl | 4 ---- 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/Project.toml b/Project.toml index 09781ff..3ae343f 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ authors = ["Vladimir Arnautov (mail@pharmcat.net)"] name = "ClinicalTrialUtilities" uuid = "535c2557-d7d0-564d-8ff9-4ae146c18cfe" -version = "0.3.1" +version = "0.3.2" [deps] Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" diff --git a/cange.log b/cange.log index 65ea9f9..f257a6f 100644 --- a/cange.log +++ b/cange.log @@ -1,3 +1,8 @@ +v0.3.2 + - bugfix fisher test + - add show + - propci for ConTab + v0.3.1 - deleteat! fix diff --git a/src/ci.jl b/src/ci.jl index ffa2e00..3677823 100644 --- a/src/ci.jl +++ b/src/ci.jl @@ -154,6 +154,12 @@ function propci(x::Int, n::Int; alpha::Real = 0.05, method = :default)::ConfInt throw(ArgumentError("unknown method!")) end end +function propci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default) + d = Dict() + d[tab.row[1]] = propci(tab.a, tab.a + tab.b; alpha = alpha, method = method) + d[tab.row[2]] = propci(tab.c, tab.c + tab.d; alpha = alpha, method = method) + d +end """ diffpropci(x1::Int, n1::Int, x2::Int, n2::Int; alpha::Real = 0.05, method::Symbol = :default)::ConfInt @@ -238,6 +244,9 @@ function rrpropci(x1::Int, n1::Int, x2::Int, n2::Int; alpha::Real = 0.05, method throw(ArgumentError("Method unknown!")) end end +function rrpropci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default)::ConfInt + rrpropci(tab.a, tab.a + tab.b, tab.c, tab.c + tab.d; alpha = alpha, method = method) +end """ orpropci(x1::Int, n1::Int, x2::Int, n2::Int; alpha::Real = 0.05, method::Symbol = :default)::ConfInt @@ -268,6 +277,9 @@ function orpropci(x1::Int, n1::Int, x2::Int, n2::Int; alpha::Real = 0.05, method throw(ArgumentError("Method unknown!")) end end +function orpropci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default)::ConfInt + orpropci(tab.a, tab.a + tab.b, tab.c, tab.c + tab.d; alpha = alpha, method = method) +end """ meanci(m::Real, σ²::Real, n::Int; alpha::Real = 0.05, method=:default)::ConfInt diff --git a/src/freque.jl b/src/freque.jl index 9963672..600ab25 100644 --- a/src/freque.jl +++ b/src/freque.jl @@ -59,7 +59,7 @@ function Base.getproperty(obj::ConTab{2, 2}, attr::Symbol) elseif attr == :d return getfield(obj, :tab)[2,2] else - error("No field!") + return getfield(obj, attr) end end @@ -178,7 +178,7 @@ function pirson(a::Matrix{Int}) tm = sum(a, dims=1)[1,:] tn = sum(a, dims=2)[:,1] num = sum(tm) - ae = Array{Real, 2}(undef, n, m) + ae = Array{Float64, 2}(undef, n, m) for im = 1:m for in = 1:n ae[in, im] = tn[in]*tm[im]/num @@ -199,7 +199,10 @@ end function fisher(a::Matrix{Int}) dist = Hypergeometric(sum(a[1, :]), sum(a[2, :]), sum(a[:, 1])) - value = min(2 * min(cdf(dist, a[1, 1]), ccdf(dist, a[1, 1])), 1.0) + l = cdf(dist, a[1, 1]) + r = ccdf(dist, a[1, 1]-1) + value = min(2 * min(r, l), 1.0) + value, l, r end function fisher(t::ConTab{2, 2}) fisher(t.tab) diff --git a/src/show.jl b/src/show.jl index da5f8a3..1f96a21 100644 --- a/src/show.jl +++ b/src/show.jl @@ -249,6 +249,24 @@ function Base.show(io::IO, obj::ConfInt) print(io, "Estimate: $(obj.estimate) ($(obj.lower) - $(obj.upper))") end +#------------------------------------------------------------------------------- +# Frequences +function Base.show(io::IO, ct::ConTab{2, 2}) + mx = Matrix{Any}(undef, 3, 3) + mx[2:3, 2:3] .= ct.tab + mx[2:3, 1] .= ct.row + mx[1, 2:3] .= ct.col + mx[1,1] = "" + println(io, "Contingency table 2X2") + println(io, "---------------------") + printmatrix(io, mx) + println(io, "---------------------") + if length(ct.sort) > 0 + println(io, ct.sort) + end +end + + #------------------------------------------------------------------------------- # OUTPUT function addspace(s::String, n::Int; first = false)::String diff --git a/test/freque.jl b/test/freque.jl index ddd9a5b..801a600 100644 --- a/test/freque.jl +++ b/test/freque.jl @@ -7,6 +7,10 @@ println(" ---------------------------------- ") frtab = ClinicalTrialUtilities.freque(df; vars=:row, alpha = 0.05) @test frtab[1,2] == 17 + @test ClinicalTrialUtilities.fisher(ClinicalTrialUtilities.ConTab([12 23; 22 33]))[2] ≈ 0.3752579856319276 + + @test ClinicalTrialUtilities.pirson(ClinicalTrialUtilities.ConTab([12 23; 22 33]))[4] ≈ 0.5856943077831229 + ctds = ClinicalTrialUtilities.contab(metadf, [:trial]; row = :group, col = :result) cmht = ClinicalTrialUtilities.metaprop(ctds, type = :or, model = :fixed, zeroadj = 0.0, tau = :ho) diff --git a/test/test.jl b/test/test.jl index 650d208..da2e160 100644 --- a/test/test.jl +++ b/test/test.jl @@ -326,10 +326,6 @@ println(" ---------------------------------- ") @test ClinicalTrialUtilities.diffmcnmwaldccci(10, 20, 11, 15; alpha = 0.05).lower ≈ -0.04741054890998043 - @test ClinicalTrialUtilities.fisher(ClinicalTrialUtilities.ConTab([12 23; 22 33])) ≈ 0.7505159712638552 - - @test ClinicalTrialUtilities.pirson(ClinicalTrialUtilities.ConTab([12 23; 22 33]))[4] ≈ 0.5856943077831229 - @test ClinicalTrialUtilities.mcnmtest(ClinicalTrialUtilities.McnmConTab([12 23; 22 33]); cc = false) ≈ 0.022222222222222223 #= /*SAS Tesing code*/ From 56097d1c3b6c4737c1525676f467718dd7f95169 Mon Sep 17 00:00:00 2001 From: PharmCat Date: Fri, 27 Nov 2020 18:18:15 +0300 Subject: [PATCH 3/3] v0.3.2 --- Project.toml | 12 +++++------- README.md | 4 ---- cange.log | 3 ++- docs/src/index.md | 4 ++++ src/ci.jl | 24 +++++++++++++++++++++++- src/freque.jl | 9 +++++++++ 6 files changed, 43 insertions(+), 13 deletions(-) diff --git a/Project.toml b/Project.toml index 3ae343f..e3bd538 100644 --- a/Project.toml +++ b/Project.toml @@ -13,7 +13,6 @@ Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" [extras] CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" @@ -24,13 +23,12 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" test = ["CSV", "Test", "Plots"] [compat] -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" +julia = "1.0, 1.1, 1.2, 1.3, 1.4, 1.5" +Distributions = "0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24" 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" QuadGK = "2.0, 2.1, 2.2, 2.3, 2.4" -SpecialFunctions = "0.8, 0.9, 0.10" -Roots = "0.7, 0.8, 1.0" -RecipesBase = "0.7, 0.8, 1.0" +SpecialFunctions = "0.8, 0.9, 0.10, 1" +Roots = "0.7, 0.8, 1" +RecipesBase = "0.7, 0.8, 1" Reexport = "0.1, 0.2" DataFrames = "0.19, 0.20" -CSV = "0.5, 0.6" diff --git a/README.md b/README.md index 38b6e37..810739a 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,6 @@ [![Coverage Status](https://coveralls.io/repos/github/PharmCat/ClinicalTrialUtilities.jl/badge.svg?branch=master)](https://coveralls.io/github/PharmCat/ClinicalTrialUtilities.jl?branch=master) [![Latest docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://pharmcat.github.io/ClinicalTrialUtilities.jl/dev/) -## Difference since v0.3.0 - - Wrong Equivalence Hypothesis alpha level! Use 0.2.7 or 0.3.1 version. - ## Description The package is designed to perform calculations related to the planning and analysis of the results of clinical trials. The package includes the basic functions described below, as well as a few modules to perform specific calculations. diff --git a/cange.log b/cange.log index f257a6f..ef7e3e1 100644 --- a/cange.log +++ b/cange.log @@ -1,7 +1,8 @@ v0.3.2 - bugfix fisher test - add show - - propci for ConTab + - propci for ConTab + - bump dependencies v0.3.1 diff --git a/docs/src/index.md b/docs/src/index.md index b780caa..a2f8ad1 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -29,6 +29,10 @@ When ctpower/ctsamplen used: - :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; +## Invalidated version v0.3.0 (removed from release page) + + Wrong Equivalence Hypothesis alpha level! Use 0.2.7, 0.3.1 version or higher. + ## Contents ```@contents diff --git a/src/ci.jl b/src/ci.jl index 3677823..a7fc75d 100644 --- a/src/ci.jl +++ b/src/ci.jl @@ -154,6 +154,11 @@ function propci(x::Int, n::Int; alpha::Real = 0.05, method = :default)::ConfInt throw(ArgumentError("unknown method!")) end end +""" + propci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default) + +Confidence interval for proportions a / (a + b) and c / (c + d) +""" function propci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default) d = Dict() d[tab.row[1]] = propci(tab.a, tab.a + tab.b; alpha = alpha, method = method) @@ -192,6 +197,9 @@ function diffpropci(x1::Int, n1::Int, x2::Int, n2::Int; alpha::Real = 0.05, meth if alpha >= 1.0 || alpha <= 0.0 throw(ArgumentError("Alpha shold be > 0.0 and < 1.0")) end + if x1 > n1 || x2 > n2 + throw(ArgumentError("X cann't be more than N")) + end if method == :nhs return propdiffnhsci(x1, n1, x2, n2, alpha) elseif method == :nhscc @@ -212,7 +220,11 @@ function diffpropci(x1::Int, n1::Int, x2::Int, n2::Int; alpha::Real = 0.05, meth throw(ArgumentError("Method unknown!")) end end -#TEST +""" + diffpropci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default)::ConfInt + +Confidence interval for proportion difference: (a / (a + b)) - (c / (c + d)) +""" function diffpropci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default)::ConfInt diffpropci(tab.a, tab.a + tab.b, tab.c, tab.c + tab.d; alpha = alpha, method = method) end @@ -244,6 +256,11 @@ function rrpropci(x1::Int, n1::Int, x2::Int, n2::Int; alpha::Real = 0.05, method throw(ArgumentError("Method unknown!")) end end +""" + rrpropci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default)::ConfInt + +Confidence interval for relative risk. +""" function rrpropci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default)::ConfInt rrpropci(tab.a, tab.a + tab.b, tab.c, tab.c + tab.d; alpha = alpha, method = method) end @@ -277,6 +294,11 @@ function orpropci(x1::Int, n1::Int, x2::Int, n2::Int; alpha::Real = 0.05, method throw(ArgumentError("Method unknown!")) end end +""" + orpropci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default)::ConfInt + +Confidence interval for odd ratio. +""" function orpropci(tab::ConTab{2,2}; alpha::Real = 0.05, method::Symbol = :default)::ConfInt orpropci(tab.a, tab.a + tab.b, tab.c, tab.c + tab.d; alpha = alpha, method = method) end diff --git a/src/freque.jl b/src/freque.jl index 600ab25..0d677c7 100644 --- a/src/freque.jl +++ b/src/freque.jl @@ -129,7 +129,16 @@ function contab(data::DataFrame, sort; row::Symbol, col::Symbol) end return DataSet(result) end +""" + contab(m; row = nothing, col = nothing) +Make contingency table. +""" +function contab(m::Matrix; row = nothing, col = nothing) + if isa(row, Nothing) row = Vector{Symbol}(undef, size(m, 1)) .= Symbol("") end + if isa(col, Nothing) col = Vector{Symbol}(undef, size(m, 2)) .= Symbol("") end + ConTab(m, row, col) +end """ mcnmcontab """