test_relative_risk.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import pytest
  2. import numpy as np
  3. from numpy.testing import assert_allclose, assert_equal
  4. from scipy.stats.contingency import relative_risk
  5. # Test just the calculation of the relative risk, including edge
  6. # cases that result in a relative risk of 0, inf or nan.
  7. @pytest.mark.parametrize(
  8. 'exposed_cases, exposed_total, control_cases, control_total, expected_rr',
  9. [(1, 4, 3, 8, 0.25 / 0.375),
  10. (0, 10, 5, 20, 0),
  11. (0, 10, 0, 20, np.nan),
  12. (5, 15, 0, 20, np.inf)]
  13. )
  14. def test_relative_risk(exposed_cases, exposed_total,
  15. control_cases, control_total, expected_rr):
  16. result = relative_risk(exposed_cases, exposed_total,
  17. control_cases, control_total)
  18. assert_allclose(result.relative_risk, expected_rr, rtol=1e-13)
  19. def test_relative_risk_confidence_interval():
  20. result = relative_risk(exposed_cases=16, exposed_total=128,
  21. control_cases=24, control_total=256)
  22. rr = result.relative_risk
  23. ci = result.confidence_interval(confidence_level=0.95)
  24. # The corresponding calculation in R using the epitools package.
  25. #
  26. # > library(epitools)
  27. # > c <- matrix(c(232, 112, 24, 16), nrow=2)
  28. # > result <- riskratio(c)
  29. # > result$measure
  30. # risk ratio with 95% C.I.
  31. # Predictor estimate lower upper
  32. # Exposed1 1.000000 NA NA
  33. # Exposed2 1.333333 0.7347317 2.419628
  34. #
  35. # The last line is the result that we want.
  36. assert_allclose(rr, 4/3)
  37. assert_allclose((ci.low, ci.high), (0.7347317, 2.419628), rtol=5e-7)
  38. def test_relative_risk_ci_conflevel0():
  39. result = relative_risk(exposed_cases=4, exposed_total=12,
  40. control_cases=5, control_total=30)
  41. rr = result.relative_risk
  42. assert_allclose(rr, 2.0, rtol=1e-14)
  43. ci = result.confidence_interval(0)
  44. assert_allclose((ci.low, ci.high), (2.0, 2.0), rtol=1e-12)
  45. def test_relative_risk_ci_conflevel1():
  46. result = relative_risk(exposed_cases=4, exposed_total=12,
  47. control_cases=5, control_total=30)
  48. ci = result.confidence_interval(1)
  49. assert_equal((ci.low, ci.high), (0, np.inf))
  50. def test_relative_risk_ci_edge_cases_00():
  51. result = relative_risk(exposed_cases=0, exposed_total=12,
  52. control_cases=0, control_total=30)
  53. assert_equal(result.relative_risk, np.nan)
  54. ci = result.confidence_interval()
  55. assert_equal((ci.low, ci.high), (np.nan, np.nan))
  56. def test_relative_risk_ci_edge_cases_01():
  57. result = relative_risk(exposed_cases=0, exposed_total=12,
  58. control_cases=1, control_total=30)
  59. assert_equal(result.relative_risk, 0)
  60. ci = result.confidence_interval()
  61. assert_equal((ci.low, ci.high), (0.0, np.nan))
  62. def test_relative_risk_ci_edge_cases_10():
  63. result = relative_risk(exposed_cases=1, exposed_total=12,
  64. control_cases=0, control_total=30)
  65. assert_equal(result.relative_risk, np.inf)
  66. ci = result.confidence_interval()
  67. assert_equal((ci.low, ci.high), (np.nan, np.inf))
  68. @pytest.mark.parametrize('ec, et, cc, ct', [(0, 0, 10, 20),
  69. (-1, 10, 1, 5),
  70. (1, 10, 0, 0),
  71. (1, 10, -1, 4)])
  72. def test_relative_risk_bad_value(ec, et, cc, ct):
  73. with pytest.raises(ValueError, match="must be an integer not less than"):
  74. relative_risk(ec, et, cc, ct)
  75. def test_relative_risk_bad_type():
  76. with pytest.raises(TypeError, match="must be an integer"):
  77. relative_risk(1, 10, 2.0, 40)