tests/testthat/test-comorbid.R

# Copyright (C) 2014 - 2015  Jack O. Wasey
#
# This file is part of icd9.
#
# icd9 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# icd9 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with icd9. If not, see <http:#www.gnu.org/licenses/>.

context("comorbidities")

library(magrittr, quietly = TRUE, warn.conflicts = FALSE)

test_that("try to induce c++ segfault bug", {
  expect_error(icd9Comorbid(ahrqTestDat, ahrqComorbid, isShort = TRUE), NA)
})

test_that("ahrq make sure all the children are listed in the saved data.", {
  skip("this is not true because we don't fill in EVERY (unreal) possible code
       when there is odd specification of the range in the SAS code.")
  for (i in names(ahrqComorbid))
    expect_true(setequal(icd9ChildrenShort(ahrqComorbid[[i]], onlyReal = FALSE), ahrqComorbid[[i]]),
                info = paste("missing from saved ahrq comorbid (", i, "): ",
                             paste(setdiff(icd9ChildrenShort(ahrqComorbid[[i]], onlyReal = FALSE), ahrqComorbid[[i]]),
                                   collapse = ", "
                             )
                )
    )
})

test_that("Elixhauser make sure all the children are listed in the saved data.", {
  for (i in elixComorbid)
    expect_equal(icd9ChildrenShort(i, onlyReal = FALSE), sort(i))
})

test_that("Quan Charlson make sure all the children are listed in the saved data.", {
  for (i in quanDeyoComorbid)
    expect_equal(icd9ChildrenShort(i, onlyReal = FALSE), sort(i))
})

test_that("Quan Elixhauser make sure all the children are listed in the saved data.", {
  for (i in quanElixComorbid)
    expect_equal(icd9ChildrenShort(i, onlyReal = FALSE), sort(i))
})

test_that("icd9 comorbidities are created correctly, and logical to binary conversion ok", {
  ptdf <- icd9Comorbid(icd9df = patientData, isShort = TRUE,
                       icd9Mapping = ahrqComorbid,
                       visitId = "visitId", return.df = TRUE)

  expect_equal(names(ptdf), c("visitId", names(ahrqComorbid)))

  expect_true(all(sapply(names(ahrqComorbid),
                         function(x)
                           class(ptdf[, x])) == "logical"))
  ptdflogical <- logicalToBinary(ptdf)
  expect_true(all(sapply(names(ahrqComorbid),
                         function(x)
                           class(ptdflogical[, x])) == "integer"))
  # do not expect all the rest of patient data to be returned - we
  # aren't responsible for aggregating other fields by visitId!
  expect_equal(dim(ptdf),
               c(length(unique(patientData[["visitId"]])),
                 1 + length(ahrqComorbid)))
  expect_true(
    setequal(names(ptdf), c("visitId", names(ahrqComorbid))))
  expect_true(
    setequal(names(ptdflogical), c("visitId", names(ahrqComorbid))))

  expect_equal(
    logicalToBinary(data.frame(a = c("jack", "hayley"),
                               b = c(TRUE, FALSE),
                               f = c(TRUE, TRUE))),
    data.frame(a = c("jack", "hayley"),
               b = c(1, 0),
               f = c(1, 1))
  )
})

test_that("ahrq icd9 mappings generated from the current generation code", {
  skip_on_cran()
  # same but from source data. Should be absolutely identical.
  expect_equal(ahrqComorbid, parseAhrqSas(save = FALSE))
  # same but from source data. Should be absolutely identical.
  expect_equivalent(icd9GetInvalidMappingShort(ahrqComorbid), list())
})

test_that("Quan Charlson icd9 mappings are all
            generated from the current generation code", {
              expect_identical(quanDeyoComorbid,
                               parseQuanDeyoSas(condense = FALSE, save = FALSE))
              expect_equivalent(icd9GetInvalidMappingShort(quanDeyoComorbid), list())
            })
test_that("Quan Elixhauser icd9 mappings are all
            generated from the current generation code", {
              expect_identical(quanElixComorbid,
                               parseQuanElix(condense = FALSE, save = FALSE))
              expect_equivalent(icd9GetInvalidMappingShort(quanElixComorbid), list())
            })
test_that("Elixhauser icd9 mappings are all
            generated from the current generation code", {

              expect_identical(elixComorbid,
                               parseElix(condense = FALSE, save = FALSE))
              expect_equivalent(icd9GetInvalidMappingShort(elixComorbid), list())
            })

test_that("can condense the big lists of comorbidities without errors", {
  # this is a useful but slow (8s on my PC) test because the data weren't
  # generated by just expanding base ranges (which is how the condense works in
  # reverse)

  skip_on_cran()
  skip_slow_tests()

  for (onlyReal in c(TRUE, FALSE)) {
    if (onlyReal) {
      expect_warning(ahrq <- lapply(ahrqComorbid, icd9CondenseShort, onlyReal = onlyReal))
      expect_warning(quanDeyo <- lapply(quanDeyoComorbid, icd9Condense, onlyReal))
      expect_warning(quanElix <- lapply(quanElixComorbid,
                                     icd9Condense, onlyReal))
      expect_warning(elix <- lapply(elixComorbid, icd9Condense, onlyReal))
    }
    else {
      expect_warning(ahrq <- lapply(ahrqComorbid, icd9CondenseShort, onlyReal), NA)
      expect_warning(quanDeyo <- lapply(quanDeyoComorbid, icd9CondenseShort, onlyReal), NA)
      expect_warning(quanElix <- lapply(quanElixComorbid, icd9CondenseShort, onlyReal), NA)
      expect_warning(elix <- lapply(elixComorbid, icd9CondenseShort, onlyReal), NA)
    }

    expect_is(ahrq, class = "list")
    expect_is(elix, class = "list")
    expect_is(quanDeyo, class = "list")
    expect_is(quanElix, class = "list")
  }
})


test_that("icd9Hierarchy as saved in data can be recreated", {
  skip("this is 15 minutes alone, so skip this and run manually when needed")
  skip_slow_tests()
  skip_online_tests()
  expect_equal(icd9BuildChaptersHierarchy(save = FALSE),
               icd9::icd9Hierarchy)
})

# the following test is dependent on Buildilability and consistency of
# http://www.icd9data.com because there is no machine readable CDC or CMS file
# with this data.
test_that("icd9Chapters, etc. as saved in data can be recreated", {
  skip_on_cran() # and/or skip_on_travis()
  skip_on_travis()
  skip_online_tests()
  res <- parseIcd9Chapters(year = "2014", save = FALSE)
  expect_equal(res$icd9Chapters, icd9::icd9Chapters)
  expect_equal(res$icd9ChaptersSub, icd9::icd9ChaptersSub)
  expect_equal(res$icd9ChaptersMajor, icd9::icd9ChaptersMajor)
})

test_that("AHRQ interpretation at least returns something reasonable", {
  skip_slow_tests()
  result <- parseAhrqSas(sasPath = system.file("extdata",
                                               "comformat2012-2013.txt",
                                               package = "icd9"), save = FALSE)
  expect_that(result, is_a("list"))
  expect_true(length(result) > 10)
})

test_that("Charlson Deyo doesn't double count disease with two severities", {
  expect_false(any(quanDeyoComorbid[["Mild Liver Disease"]] %in%
                     quanDeyoComorbid[["Moderate or Severe Liver Disease"]] ))
  expect_false(any(quanDeyoComorbid[["Cancer"]] %in%
                     quanDeyoComorbid[["Metastatic Carcinoma"]] ))
  expect_false(any(quanDeyoComorbid[["Diabetes without complications"]] %in%
                     quanDeyoComorbid[["Diabetes with complications"]] ))
})

test_that("Elixhauser doesn't double count disease with multiple severities", {
  expect_false(any(quanElixComorbid[["dm.uncomp"]] %in%
                     quanElixComorbid[["dm.comp"]] ))
  expect_false(any(quanElixComorbid[["solid.tumor"]] %in%
                     quanElixComorbid[["mets"]] ))
  expect_false(any(elixComorbid[["dm.uncomp"]] %in%
                     elixComorbid[["dm.comp"]] ))
  expect_false(any(elixComorbid[["solid.tumor"]] %in%
                     elixComorbid[["mets"]] ))
  expect_false(any(ahrqComorbid[["DM"]] %in% ahrqComorbid[["DMCX"]] ))
  expect_false(any(ahrqComorbid[["TUMOR"]] %in% ahrqComorbid[["METS"]] ))
})

# next couple of tests demonstrate that the interpreted data is correctly
# transcribed in cases where the data is structured differently, and also
# affirms that 'child' codes are included in the RData mappings in the package.
# E.g. if the mapping specifies "044", we do expect 111 total codes to be in the
# mapping 0440 04400 04401 etc. Ahrq
test_that("ICD-9 codes from SAS source AHRQ exist", {
  # specific codes that have had parsing problems in the past:
  expect_true("3970" %in% ahrqComorbid$Valvular)
  expect_true("39706" %in% ahrqComorbid$Valvular)
  expect_true("3971" %in% ahrqComorbid$Valvular)
  expect_true("3979" %in% ahrqComorbid$Valvular)
  # SAS source is "7463 "-"7466 "
  expect_true("7463" %in% ahrqComorbid$Valvular)
  expect_true("7466" %in% ahrqComorbid$Valvular)
  expect_true("74645" %in% ahrqComorbid$Valvular)
  # "3420 "-"3449 ",
  # "43820"-"43853",
  # "78072"         = "PARA"      /* Paralysis */
  expect_true("43820" %in% ahrqComorbid$Paralysis)
  expect_true("43822" %in% ahrqComorbid$Paralysis)
  expect_true("43850" %in% ahrqComorbid$Paralysis)
  expect_true("43852" %in% ahrqComorbid$Paralysis)
  expect_true("43853" %in% ahrqComorbid$Paralysis)
  # although 4385 implies an overly broad range, all its children are in the requested range, so it should appear.
  expect_true("4383" %in% ahrqComorbid$Paralysis)
  expect_true("4384" %in% ahrqComorbid$Paralysis)
  expect_true("4385" %in% ahrqComorbid$Paralysis)
  expect_false("438" %in% ahrqComorbid$Paralysis)
  expect_false("4386" %in% ahrqComorbid$Paralysis)
  # neuro other problem codes
  #   "3411 "-"3419 ",
  #   "34500"-"34511",
  #   "3452 "-"3453 ",
  #   "34540"-"34591",
  #   "34700"-"34701",
  #   "34710"-"34711",
  expect_true("3337" %in% ahrqComorbid$NeuroOther) # single value
  expect_true("33371" %in% ahrqComorbid$NeuroOther) # single value sub-code - zero not defined in 2015
  expect_true("494" %in% ahrqComorbid$Pulmonary) # top-level at start of range
  expect_true("4940" %in% ahrqComorbid$Pulmonary) # value within range
  expect_true("49400" %in% ahrqComorbid$Pulmonary) # sub-value within range
  expect_true("3450" %in% ahrqComorbid$NeuroOther)
  expect_true("34500" %in% ahrqComorbid$NeuroOther)
  expect_true("3451" %in% ahrqComorbid$NeuroOther)
  expect_true("34511" %in% ahrqComorbid$NeuroOther)
  expect_true("34519" %in% ahrqComorbid$NeuroOther)
  expect_true("3452" %in% ahrqComorbid$NeuroOther)
  expect_true("34529" %in% ahrqComorbid$NeuroOther)
  expect_true("3453" %in% ahrqComorbid$NeuroOther)
  expect_true("34539" %in% ahrqComorbid$NeuroOther)
  expect_true("3459" %in% ahrqComorbid$NeuroOther)
  expect_true("34599" %in% ahrqComorbid$NeuroOther) # by implication
  #   "490  "-"4928 ",
  #   "49300"-"49392", # this is all of asthma
  #   "494  "-"4941 ", # bronchiectasis is just 494, 4940 and 4941
  #   "4950 "-"505  ",
  #   "5064 "         = "CHRNLUNG"  /* Chronic pulmonary disease */
  expect_true("492" %in% ahrqComorbid$Pulmonary) # implied, and more below
  expect_true("4929" %in% ahrqComorbid$Pulmonary)
  expect_true("4920" %in% ahrqComorbid$Pulmonary)
  expect_true("4928" %in% ahrqComorbid$Pulmonary)
  expect_true("493" %in% ahrqComorbid$Pulmonary)
  expect_true("49392" %in% ahrqComorbid$Pulmonary)
  expect_true("49300" %in% ahrqComorbid$Pulmonary)
  expect_true("49322" %in% ahrqComorbid$Pulmonary) # implied intermediate
  expect_true("494" %in% ahrqComorbid$Pulmonary)
  expect_true("4940" %in% ahrqComorbid$Pulmonary)
  expect_true("4941" %in% ahrqComorbid$Pulmonary)
  expect_true("49499" %in% ahrqComorbid$Pulmonary) # implied
  #   "25000"-"25033",
  #   "64800"-"64804",
  #   "24900"-"24931" = "DM"        /* Diabetes w/o chronic complications*/
  expect_false("249" %in% ahrqComorbid$DM)
  expect_false("2494" %in% ahrqComorbid$DM)
  expect_false("24941" %in% ahrqComorbid$DM)
  expect_true("24900" %in% ahrqComorbid$DM)
  expect_true("24931" %in% ahrqComorbid$DM)
  expect_true("24939" %in% ahrqComorbid$DM)
  expect_true("2493" %in% ahrqComorbid$DM)
  expect_false("2504" %in% ahrqComorbid$DM)
  expect_false("25043" %in% ahrqComorbid$DM)
  expect_false("250" %in% ahrqComorbid$DM)
  expect_true("25000" %in% ahrqComorbid$DM)
  expect_true("25029" %in% ahrqComorbid$DM) # implied
  expect_true("25033" %in% ahrqComorbid$DM)
  expect_true("2503" %in% ahrqComorbid$DM) # implied
  expect_true("25039" %in% ahrqComorbid$DM) # implied
  #   "25040"-"25093",
  #   "7751 ",
  #   "24940"-"24991" = "DMCX"      /* Diabetes w/ chronic complications */
  expect_false("250" %in% ahrqComorbid$DMcx)
  expect_false("2503" %in% ahrqComorbid$DMcx)
  expect_true("2509" %in% ahrqComorbid$DMcx) # implied
  expect_true("25093" %in% ahrqComorbid$DMcx)
  expect_true("25099" %in% ahrqComorbid$DMcx) # implied
  expect_false("249" %in% ahrqComorbid$DMcx)
  expect_true("2499" %in% ahrqComorbid$DMcx)
  expect_true("2498" %in% ahrqComorbid$DMcx)
  expect_true("24999" %in% ahrqComorbid$DMcx)
  expect_true("24991" %in% ahrqComorbid$DMcx)
  #   "243  "-"2442 ",
  #   "2448 ",
  #   "2449 "         = "HYPOTHY"   /* Hypothyroidism */
  expect_false("244" %in% ahrqComorbid$Hypothyroid) # some children are not included
  expect_false("2443" %in% ahrqComorbid$Hypothyroid) # explicitly excluded by Quan
  expect_false("24430" %in% ahrqComorbid$Hypothyroid) # implied exclusion
  expect_true("2442" %in% ahrqComorbid$Hypothyroid)
  expect_true("243" %in% ahrqComorbid$Hypothyroid) # top level billable code
  expect_true("2430" %in% ahrqComorbid$Hypothyroid) # implied, doesn't exist
  expect_true("24300" %in% ahrqComorbid$Hypothyroid) # implied
  expect_true("2448" %in% ahrqComorbid$Hypothyroid)
  expect_true("2449" %in% ahrqComorbid$Hypothyroid)
  expect_true("24480" %in% ahrqComorbid$Hypothyroid)
  expect_true("24499" %in% ahrqComorbid$Hypothyroid)
  #      "V560 "-"V5632",
  expect_true("V560" %in% ahrqComorbid$Renal)
  expect_true("V563" %in% ahrqComorbid$Renal)
  expect_true("V5632" %in% ahrqComorbid$Renal)
  expect_true("V568" %in% ahrqComorbid$Renal)
  expect_false("V56" %in% ahrqComorbid$Renal)
  #   "20000"-"20238",
  #   "20250"-"20301",
  #   "2386 ",
  #   "2733 ",
  #   "20302"-"20382" = "LYMPH"     /* Lymphoma */
  expect_true("200" %in% ahrqComorbid$Lymphoma)
  expect_true("2000" %in% ahrqComorbid$Lymphoma)
  expect_true("20000" %in% ahrqComorbid$Lymphoma)
  expect_true("201" %in% ahrqComorbid$Lymphoma)
  expect_true("20100" %in% ahrqComorbid$Lymphoma)
  expect_true("20199" %in% ahrqComorbid$Lymphoma)
  expect_false("202" %in% ahrqComorbid$Lymphoma)
  expect_false("2024" %in% ahrqComorbid$Lymphoma)
  expect_false("20240" %in% ahrqComorbid$Lymphoma)
  expect_false("20248" %in% ahrqComorbid$Lymphoma)
  expect_false("20249" %in% ahrqComorbid$Lymphoma)
  expect_true("2025" %in% ahrqComorbid$Lymphoma)
  expect_true("20250" %in% ahrqComorbid$Lymphoma)
  expect_true("20258" %in% ahrqComorbid$Lymphoma)
  expect_true("20259" %in% ahrqComorbid$Lymphoma)
  expect_true("20298" %in% ahrqComorbid$Lymphoma)
  expect_true("20299" %in% ahrqComorbid$Lymphoma)
  # 2030 and 203 are parents: problem because this range is split for some reason
  expect_true("2031" %in% ahrqComorbid$Lymphoma)
  expect_true("20310" %in% ahrqComorbid$Lymphoma)
  expect_true("20300" %in% ahrqComorbid$Lymphoma)
  expect_true("20301" %in% ahrqComorbid$Lymphoma)
  # "1960 "-"1991 ",
  expect_true("196" %in% ahrqComorbid$Mets)
  expect_true("1960" %in% ahrqComorbid$Mets)
  expect_true("19600" %in% ahrqComorbid$Mets)
  expect_true("1969" %in% ahrqComorbid$Mets)
  expect_true("19699" %in% ahrqComorbid$Mets)
  expect_true("197" %in% ahrqComorbid$Mets)
  expect_true("1970" %in% ahrqComorbid$Mets)
  expect_true("19700" %in% ahrqComorbid$Mets)
  expect_true("19799" %in% ahrqComorbid$Mets)
  expect_true("198" %in% ahrqComorbid$Mets)
  expect_true("1980" %in% ahrqComorbid$Mets)
  expect_true("19800" %in% ahrqComorbid$Mets)
  expect_true("19899" %in% ahrqComorbid$Mets)
  expect_true("1990" %in% ahrqComorbid$Mets)
  expect_true("19900" %in% ahrqComorbid$Mets)
  expect_true("19909" %in% ahrqComorbid$Mets)
  expect_true("1991" %in% ahrqComorbid$Mets)
  expect_true("19910" %in% ahrqComorbid$Mets)
  expect_true("19919" %in% ahrqComorbid$Mets)
  expect_false("199" %in% ahrqComorbid$Mets)
  expect_false("1992" %in% ahrqComorbid$Mets)
  expect_false("19920" %in% ahrqComorbid$Mets)
  expect_false("19929" %in% ahrqComorbid$Mets)
  expect_false("1993" %in% ahrqComorbid$Mets) # implied
  expect_false("19930" %in% ahrqComorbid$Mets) # implied
  expect_false("19999" %in% ahrqComorbid$Mets) # implied
  #   "179  "-"1958 ",
  #   "20900"-"20924",
  #   "20925"-"2093 ",
  #   "20930"-"20936",
  expect_true("195" %in% ahrqComorbid$Tumor) # all children, so implied
  expect_true("1950" %in% ahrqComorbid$Tumor)
  expect_true("1958" %in% ahrqComorbid$Tumor)
  expect_true("19589" %in% ahrqComorbid$Tumor)
  expect_true("1959" %in% ahrqComorbid$Tumor)
  expect_true("19599" %in% ahrqComorbid$Tumor)
  expect_false("209" %in% ahrqComorbid$Tumor)
  expect_false("2094" %in% ahrqComorbid$Tumor)
  expect_false("20940" %in% ahrqComorbid$Tumor)
  expect_false("2099" %in% ahrqComorbid$Tumor)
  expect_false("20999" %in% ahrqComorbid$Tumor)
  expect_false("2097" %in% ahrqComorbid$Tumor)
  expect_false("20979" %in% ahrqComorbid$Tumor)
  expect_true("20936" %in% ahrqComorbid$Tumor)
  expect_true("2093" %in% ahrqComorbid$Tumor)
  expect_true("20930" %in% ahrqComorbid$Tumor)
  expect_true("20939" %in% ahrqComorbid$Tumor)
  expect_true("2090" %in% ahrqComorbid$Tumor)
  expect_true("2091" %in% ahrqComorbid$Tumor)
  # is range split between definitions? ideally this would be included, but it
  # is a corner case e.g. 2092
  expect_true("20900" %in% ahrqComorbid$Tumor)
  expect_true("20910" %in% ahrqComorbid$Tumor)
  expect_true("20920" %in% ahrqComorbid$Tumor)
  expect_true("20907" %in% ahrqComorbid$Tumor)
  expect_true("20917" %in% ahrqComorbid$Tumor)
  expect_true("20927" %in% ahrqComorbid$Tumor)
  expect_true("20909" %in% ahrqComorbid$Tumor)
  expect_true("20919" %in% ahrqComorbid$Tumor)
  expect_true("20929" %in% ahrqComorbid$Tumor)
  #   "2871 ",
  #   "2873 "-"2875 ", # coag
  expect_true("2871" %in% ahrqComorbid$Coagulopathy)
  expect_true("28710" %in% ahrqComorbid$Coagulopathy) # doesn't exist but really should work simply
  expect_true("28719" %in% ahrqComorbid$Coagulopathy) # doesn't exist but really should work simply
  expect_false("287" %in% ahrqComorbid$Coagulopathy)
  expect_false("2872" %in% ahrqComorbid$Coagulopathy)
  expect_false("28720" %in% ahrqComorbid$Coagulopathy)
  expect_false("28729" %in% ahrqComorbid$Coagulopathy)
  expect_true("2873" %in% ahrqComorbid$Coagulopathy)
  expect_true("28730" %in% ahrqComorbid$Coagulopathy)
  expect_true("28739" %in% ahrqComorbid$Coagulopathy)
  expect_true("2874" %in% ahrqComorbid$Coagulopathy)
  expect_true("28741" %in% ahrqComorbid$Coagulopathy)
  expect_true("28749" %in% ahrqComorbid$Coagulopathy)
  expect_true("2875" %in% ahrqComorbid$Coagulopathy)
  expect_true("28759" %in% ahrqComorbid$Coagulopathy)
  expect_false("2876" %in% ahrqComorbid$Coagulopathy)
  expect_false("28760" %in% ahrqComorbid$Coagulopathy)
  expect_false("28769" %in% ahrqComorbid$Coagulopathy)
  expect_false("2878" %in% ahrqComorbid$Coagulopathy)
  expect_false("2879" %in% ahrqComorbid$Coagulopathy)
  expect_false("28799" %in% ahrqComorbid$Coagulopathy)
  #   "2910 "-"2913 ",
  #   "2915 ",
  #   "2918 ",
  #   "29181",
  #   "29182",
  #   "29189",
  #   "2919 ",
  #   "30300"-"30393",
  #   "30500"-"30503" = "ALCOHOL"   /* Alcohol abuse */
  expect_true("2910" %in% ahrqComorbid$Alcohol)
  expect_true("2913" %in% ahrqComorbid$Alcohol)
  expect_true("2915" %in% ahrqComorbid$Alcohol)
  expect_true("2918" %in% ahrqComorbid$Alcohol)
  expect_true("29181" %in% ahrqComorbid$Alcohol)
  expect_true("29182" %in% ahrqComorbid$Alcohol)
  expect_true("29189" %in% ahrqComorbid$Alcohol)
  expect_true("2919" %in% ahrqComorbid$Alcohol)
  expect_false("291" %in% ahrqComorbid$Alcohol)
  expect_false("2914" %in% ahrqComorbid$Alcohol)
  expect_false("29140" %in% ahrqComorbid$Alcohol)
  expect_false("29149" %in% ahrqComorbid$Alcohol)
  #   "2920 ",
  #   "29282"-"29289",
  #   "2929 ",
  #   "30400"-"30493",
  #   "30520"-"30593",
  #   "64830"-"64834" = "DRUG"      /* Drug abuse */
  expect_true("304" %in% ahrqComorbid$Drugs)
  expect_true("3040" %in% ahrqComorbid$Drugs)
  expect_true("30400" %in% ahrqComorbid$Drugs)
  expect_true("3049" %in% ahrqComorbid$Drugs)
  expect_true("30493" %in% ahrqComorbid$Drugs)
  expect_false("305" %in% ahrqComorbid$Drugs)
  expect_false("3050" %in% ahrqComorbid$Drugs)
  expect_false("30500" %in% ahrqComorbid$Drugs)
  expect_false("3051" %in% ahrqComorbid$Drugs)
  expect_false("30510" %in% ahrqComorbid$Drugs)
  expect_true("3052" %in% ahrqComorbid$Drugs)
  expect_true("30520" %in% ahrqComorbid$Drugs)
  expect_true("30523" %in% ahrqComorbid$Drugs)
  expect_true("3059" %in% ahrqComorbid$Drugs)
  expect_true("30593" %in% ahrqComorbid$Drugs)

})

test_that("ICD-9 codes from SAS source for Quan Deyo Charlson exist", {
  # Quan Deyo Charlson
  # top level single value
  expect_true("410" %in% quanDeyoComorbid$MI)
  # this is not included (410 and 412 defined)
  expect_false("411" %in% quanDeyoComorbid$MI)
  # this is not included (410 and 412 defined)
  expect_false("41199" %in% quanDeyoComorbid$MI)
  # midlevel value, not from range
  expect_true("4100" %in% quanDeyoComorbid$MI)
  # lower-level value, not from range
  expect_true("41001" %in% quanDeyoComorbid$MI)
  # midlevel definition
  expect_true("2504" %in% quanDeyoComorbid$DMcx)
  # midlevel definition lower-level code
  expect_true("25041" %in% quanDeyoComorbid$DMcx)

})

# the following two tests cover the mappings in which there was no source SAS
# data, but the numbers were transcribed manually. This is therefore testing a
# little of the transcription, and also the elobration of codes definied in
# ranges
test_that("sample of ICD-9 codes from manually specified Quan Elix mapping exist", {
  expect_true("2500" %in% quanElixComorbid$DM)
  expect_true("2501" %in% quanElixComorbid$DM)
  expect_true("25011" %in% quanElixComorbid$DM)
  expect_true("276" %in% quanElixComorbid$FluidsLytes)
  expect_true("2761" %in% quanElixComorbid$FluidsLytes)
  expect_true("27612" %in% quanElixComorbid$FluidsLytes)
  # top level should not be included automatically
  expect_false("710" %in% quanElixComorbid$FluidsLytes)
})

test_that("sample of ICD-9 codes from manually specified Elixhauser mapping exist", {
  expect_true("09320" %in% elixComorbid$Valvular)
  expect_true("3971" %in% elixComorbid$Valvular)
  expect_true("V560" %in% elixComorbid$Renal)
  expect_true("V1090" %in% elixComorbid$Tumor) # child at end of a V range
})

test_that("github #34 - short and long custom map give different results", {
  mydf <- data.frame(visitId = c("a", "b", "b", "c"),
                     icd9 = c("1", "010", "10", "20"))

  mymaps <- list(jack = c("1", "2", "3"), alf = c("010", "20"))
  mymapd <- lapply(mymaps, icd9ShortToDecimal)

  expect_identical(
    icd9Comorbid(mydf, icd9Mapping = mymaps, isShort = TRUE),
    icd9Comorbid(mydf, icd9Mapping = mymapd, isShort = FALSE))

})

test_that("no NA values in the co-morbidity lists", {
  expect_false(anyNA(unlist(unname(ahrqComorbid))))
  expect_false(anyNA(unlist(unname(quanDeyoComorbid))))
  expect_false(anyNA(unlist(unname(quanElixComorbid))))
  expect_false(anyNA(unlist(unname(elixComorbid))))
})

test_that("built-in icd9 to comorbidity mappings are all valid", {
  expect_true(icd9IsValidMappingShort(ahrqComorbid))
  expect_true(icd9IsValidMappingShort(quanDeyoComorbid))
  expect_true(icd9IsValidMappingShort(quanElixComorbid))
  expect_true(icd9IsValidMappingShort(elixComorbid))
})

test_that("disordered visit ids", {
  pts <- data.frame(visitId = c("2", "1", "2", "3", "3"),
                    icd9 = c("39891", "40110", "09322", "41514", "39891"))
  icd9ComorbidShort(pts, ahrqComorbid)
})

test_that("diff comorbid works", {
  expect_error(icd9DiffComorbid(bad_input)) # list, but not list of character vectors
  expect_error(icd9DiffComorbid(bad_input, bad_input))

  # no warning or error for good data
  expect_warning(res <- icd9DiffComorbid(ahrqComorbid, elixComorbid, show = FALSE), NA)
  expect_true(all(names(res) %in% c(
    "CHF", "Valvular", "PHTN", "PVD", "HTN", "HTNcx", "Paralysis",
    "NeuroOther", "Pulmonary", "DM", "DMcx", "Hypothyroid", "Renal",
    "Liver", "PUD", "HIV", "Lymphoma", "Mets", "Tumor", "Rheumatic",
    "Coagulopathy", "Obesity", "WeightLoss", "FluidsLytes", "BloodLoss",
    "Anemia", "Alcohol", "Drugs", "Psychoses", "Depression")))
  # one side diff
  expect_identical(res$Drugs[["only.y"]], character(0))
  # match
  expect_identical(res$Depression[[2]], character(0))
  expect_identical(res$Depression[[3]], character(0))

  # both, also with elements in either side set diff
  expect_equal(res$PUD$both, c("53170", "53270", "53370", "53470"))

  expect_warning(resq <- icd9DiffComorbid(quanElixComorbid, quanDeyoComorbid, show = TRUE), NA)

  expect_error(
    utils::capture.output(
      resq <- icd9DiffComorbid(quanElixComorbid, quanDeyoComorbid, show = TRUE)
      ), NA
  )

})

twoPtsFac <- data.frame(visitId = c("v01", "v01", "v02", "v02"),
                        icd9 = c("040", "000", "100", "000"),
                        stringsAsFactors = TRUE)
twoMapFac <- as.list(data.frame("malady" = c("100", "2000"),
                                "ailment" = c("003", "040"),
                                stringsAsFactors = TRUE))

test_that("comorbid quick test", {
  testres <- icd9Comorbid(twoPts, twoMap, return.df = TRUE)
  trueres <- data.frame("visitId" = c("v01", "v02"),
                        "malady" = c(FALSE, TRUE),
                        "ailment" = c(TRUE, FALSE),
                        stringsAsFactors = FALSE)
  expect_equal(testres, trueres)

  testmat <- icd9Comorbid(twoPts, twoMap, return.df = FALSE)
  truemat <- matrix(c(FALSE, TRUE, TRUE, FALSE), nrow = 2,
                    dimnames = list(c("v01", "v02"), c("malady", "ailment")))
  expect_equal(testmat, truemat)

  testresfac <- icd9Comorbid(twoPtsFac, twoMapFac, return.df = TRUE)
  trueresfac <- data.frame("visitId" = c("v01", "v02"),
                           "malady" = c(FALSE, TRUE),
                           "ailment" = c(TRUE, FALSE),
                           stringsAsFactors = TRUE)
  expect_equal(testresfac, trueresfac)
  expect_equal(icd9Comorbid(twoPtsFac, twoMapFac), truemat)

})

test_that("control params don't affect result of comorbid calc", {
  pts <- randomPatients(101, 13)
  pts$visitId <- asCharacterNoWarn(pts$visitId)
  pts$icd9 <- as.factor(pts$icd9)
  upts <- length(unique(pts$visitId))
  ac <-  lapply(ahrqComorbid, function(x) {
    f <- factor(x, levels(pts[["icd9"]]))
    f[!is.na(f)]
  })
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 1, chunkSize = 32),
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = 32)
  )
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 2, chunkSize = 32),
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 5, chunkSize = 32)
  )
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = 1),
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = 32)
  )
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 4, chunkSize = upts - 1),
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 4, chunkSize = upts)
  )
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 4, chunkSize = upts - 1),
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 4, chunkSize = upts + 1)
  )
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 4, chunkSize = upts + 1),
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 4, chunkSize = upts)
  )
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = upts - 2, ompChunkSize = 1), # nolint
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = upts + 2, ompChunkSize = 1) # nolint
  )
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = upts - 2, ompChunkSize = 11), # nolint
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = upts + 2, ompChunkSize = 11) # nolint
  )
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = upts, ompChunkSize = 1), # nolint
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = upts, ompChunkSize = 11) # nolint
  )
  expect_identical(
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field"),
    icd9ComorbidShortCpp(pts, ac, visitId = "visitId", icd9Field = "icd9Field", threads = 3, chunkSize = 3, ompChunkSize = 5) # nolint
  )
})

test_that("failing example", {
  mydf <- data.frame(visitId = c("a", "b", "c"),
                     icd9 = c("441", "412.93", "044.9"))
  cmb <- icd9ComorbidQuanDeyo(mydf, isShort = FALSE, applyHierarchy = TRUE)
  expect_false("names" %in% names(attributes(cmb)))
  icd9Charlson(mydf, isShort = FALSE)
  icd9Charlson(mydf, isShort = FALSE, return.df = TRUE)
  icd9CharlsonComorbid(cmb)
})

test_that("disordered visitIds works by default", {
  set.seed(1441)
  dat <- transform(testTwenty, visitId = sample(visitId))
  cmp <-
    tres <- icd9Comorbid(dat, ahrqComorbid, icd9Field = "icd9Code")
  cres <- icd9Comorbid(testTwenty, ahrqComorbid, icd9Field = "icd9Code")
  expect_equal(dim(tres), dim(cres))
  expect_equal(sum(tres), sum(cres))
  expect_true(setequal(rownames(tres), rownames(cres)))
  expect_equal(colnames(tres), colnames(cres))

})

test_that("comorbidities created from source data frame coded as factors", {
  v2 <- icd9WideToLong(vermont_dx)
  v2$visit_id <- as.factor(v2$visit_id)
  v2$icdCode <- as.factor(v2$icdCode)

  res <- icd9ComorbidAhrq(v2)
  res_nofactor <- vermont_dx %>% icd9WideToLong %>% icd9ComorbidAhrq
  expect_identical(res, res_nofactor)
})

Try the icd9 package in your browser

Any scripts or data that you put into this service are public.

icd9 documentation built on May 30, 2017, 2:25 a.m.