├── _config.yml ├── configure.win ├── src ├── makevars.hpp ├── makevars.h.win ├── makevars.h.win64 ├── Makevars.in ├── cutil.h ├── Makevars.win ├── .gitignore ├── fastIntToString.hpp ├── .clang-tidy ├── attr.hpp ├── test-runner.cpp ├── convert10.hpp ├── is.hpp ├── manip.hpp ├── mapplus.hpp ├── cutil.c ├── categorize.cpp ├── convert.hpp ├── refactor.hpp ├── .clang-format ├── fastIntToString.cpp ├── attr.cpp ├── appendMinor.hpp ├── util.hpp ├── relevant.hpp ├── ranges.hpp ├── range-const.hpp ├── comorbidMatMul.hpp ├── sort.hpp ├── icd_types.hpp └── children.cpp ├── R ├── sysdata.rda ├── as_char_no_warn.R ├── assign.R ├── generate.R ├── parse-icd10-pc.R ├── print.icd_comorbidity_map.R ├── bindings.R ├── vermont_dx.R ├── uranium_pathology.R └── env.R ├── man-roxygen ├── visitId.R ├── dotdotdot.R ├── icd9df.R ├── verbose.R ├── poaField.R ├── ccs-single.R ├── lang.R ├── invert.R ├── sep.R ├── whitespace_ok.R ├── toParent.R ├── warn.R ├── pc.R ├── save_pkg_data.R ├── short_map.R ├── short_code.R ├── abbrev_names.R ├── hierarchy.R ├── offline.R ├── scoring-system.R ├── leadingZeroes.R ├── poa_name.R ├── isShort.R ├── ver.R ├── mjr.R ├── return_df.R ├── dx.R ├── stringsAsFactors.R ├── return.df.R ├── mnr.R ├── icd9-any.R ├── icd9-decimal.R ├── icd9-short.R ├── parse-template.R ├── return_binary.R ├── poa.R ├── onlyBillable.R ├── billable.R ├── icd_name.R ├── defined.R ├── mapping.R ├── mapping-icd9.R ├── deprecated-icd3.R ├── visit_name.R └── widevlong.R ├── data ├── vermont_dx.rda ├── icd10_map_cc.rda ├── icd10_map_ccs.rda ├── icd10cm2019.rda ├── icd9_majors.rda ├── icd9_map_ahrq.rda ├── icd9_map_cc.rda ├── icd9_map_elix.rda ├── icd10_map_ahrq.rda ├── icd10_map_elix.rda ├── icd10_names_ccs.rda ├── icd9cm2014_leaf.rda ├── icd_map_cc_hcc.rda ├── icd10_map_ahrq_pcs.rda ├── icd10_map_charlson.rda ├── icd10_map_pccc_dx.rda ├── icd10_map_pccc_pcs.rda ├── icd10_sub_chapters.rda ├── icd9_map_charlson.rda ├── icd9_map_multi_ccs.rda ├── icd9_map_pccc_dx.rda ├── icd9_map_pccc_pcs.rda ├── icd9_map_quan_deyo.rda ├── icd9_map_quan_elix.rda ├── icd9cm_hierarchy.rda ├── uranium_pathology.rda ├── icd10_map_quan_deyo.rda ├── icd10_map_quan_elix.rda ├── icd9_map_single_ccs.rda ├── icd9_names_multi_ccs.rda └── icd9_names_single_ccs.rda ├── .aspell ├── icdwords.rds └── defaults.R ├── cleanup ├── vignettes ├── jsslogo.jpg ├── efficiency-prebuilt.pdf ├── country-lang-vers-prebuilt.pdf ├── .gitignore ├── gplv3.bib ├── efficiency.Rnw ├── country-lang-vers.Rnw └── other.bib ├── tools ├── crash-cases │ ├── icd10.R │ ├── reduce-icd10.R │ └── eigen.R ├── travis-ccache.conf ├── appveyor-yaml-check.sh ├── travis-yaml-check.sh ├── build-full.sh ├── gdb_fun.sh ├── format.sh ├── build-quick.sh ├── rprof-one-cmd.sh ├── env │ ├── rhub │ ├── rhub-san │ ├── quick │ ├── appveyor │ └── jit ├── install-full.sh ├── mk │ ├── travis-debug.mk │ ├── strip.mk │ ├── travis-macos.mk │ └── travis-nowarn.mk ├── DESCRIPTION-minimalize.sh ├── compare datasets.R ├── find_icd10cm_permutations.r ├── install-quick.sh ├── check-cran.sh ├── check-full.sh ├── configure-and-build.sh ├── bibfix.sh ├── check-plus.sh ├── find-icd-home.sh ├── check-quick.sh ├── check-env.sh └── publish.sh ├── benchmarks ├── lookup-fourth.rda ├── rtf-fourth-out.rda ├── icd-JSS3447-replication │ ├── medicalrisk_1.2.tar.gz │ ├── comorbidity_0.1.1.tar.gz │ ├── Dockerfile │ └── find_comobidity_cutoff.R ├── bench-charlson.R ├── bench-expand.R ├── bench-parse-rtf.R ├── bench-rbind-with-empty.R ├── bench-strings.R ├── bench-appendMinor.R ├── bench-dropLeadingZeroes.R ├── bench-addleadingzeroes.R ├── bench-comorbid-icd9-1e7-plain.R ├── bench-children.R ├── bench-parse-rtf-lookup-fourth.R ├── bench-fill-integer-seq-duff.cpp └── bench-class.R ├── man ├── figures │ └── README-example-1.png ├── icd9_sub_chapters.Rd ├── get_icd10cm2014.Rd ├── get_icd10cm2015.Rd ├── get_icd10cm2016.Rd ├── get_icd10cm2017.Rd ├── get_icd10cm2018.Rd ├── get_icd10cm2019.Rd ├── icd9cm2014_leaf.Rd ├── get_icd10be2017.Rd ├── get_icd10be2014_pc.Rd ├── get_icd10be2017_pc.Rd ├── get_icd10who2016.Rd ├── poa_choices.Rd ├── cr.Rd ├── get_cim10fr2019.Rd ├── get_icd10who2008fr.Rd ├── attr_short_diag.Rd ├── get_icd10cm2014_pc.Rd ├── get_icd10cm2015_pc.Rd ├── get_icd10cm2016_pc.Rd ├── get_icd10cm2017_pc.Rd ├── get_icd10cm2018_pc.Rd ├── explain_table_worker.Rd ├── uranium_pathology.Rd ├── shortcode_icd9.Rd ├── is.icd_long_data.Rd ├── as.comorbidity_map.Rd ├── sub-sub-.comorbidity_map.Rd ├── attr_decimal_diag.Rd ├── get_icd10cm_latest.Rd ├── icd10_comorbid_reduce.Rd ├── expand_range.icd10cm.Rd ├── set_icd10cm_active_year.Rd ├── with_icd10cm_version.Rd ├── get_icd10cm2019_pc.Rd ├── chapters_to_map.Rd ├── get_icd10cm_version.Rd ├── icd10_sub_chapters.Rd ├── print.comorbidity_map.Rd ├── get_defined.Rd ├── download_all_icd_data.Rd ├── guess_version.Rd ├── icd10_chapters.Rd ├── get_icd10fr2019.Rd ├── convert.Rd ├── is.icd9.Rd ├── get_icd10be2014.Rd ├── guess_short.Rd ├── expand_range_major.Rd ├── get_invalid.Rd ├── print.icd9.Rd ├── generate_neds_pts.Rd ├── icd9MajMinToCode.Rd ├── subset.Rd ├── get_icd10cm_available.Rd ├── short_to_decimal.Rd ├── get_leaf.Rd ├── apply_hier.Rd ├── set_icd_data_dir.Rd ├── icd9_map_ahrq.Rd ├── decimal_to_short.Rd ├── get_icd9cm2014_leaf.Rd ├── combine.Rd ├── get_valid.Rd ├── icd9_map_pccc.Rd ├── is_valid_major.Rd ├── is_billable.Rd ├── vermont_dx.Rd ├── icd9_map_quan_elix.Rd ├── get_billable.Rd ├── plot_comorbid.Rd └── icd10_map_ahrq_pcs.Rd ├── tests ├── testthat │ ├── github133-b.rds │ ├── test-icd10be.R │ ├── test-filter-icd10.R │ ├── test-explain-fr.R │ ├── test-spell.R │ ├── test-build-maps-icd9-kids-charl.R │ ├── test-examples.R │ ├── test-build-maps-icd9-kids-elix.R │ ├── test-data-fun.R │ ├── test-explain-icd10.R │ ├── test-build-maps-icd9-notquan.R │ ├── test-chapters-to-map.R │ ├── test-build-maps-icd10.R │ ├── test-longtowide.R │ ├── test-refactor-slow.R │ ├── test-chapters.R │ ├── test-attr.R │ ├── test-sample-data.R │ ├── test-build-maps-icd9-quan.R │ ├── test-parse-icd10.R │ ├── test-explain-who.R │ └── test-build-sysdata.R └── testthat.R ├── .Rinstignore ├── .covrignore ├── .gitconfig ├── inst └── COPYRIGHTS ├── .lintr ├── codecov.yml ├── data-raw └── .gitignore ├── icd.Rproj ├── .gitattributes ├── .gitignore ├── cran-comments.md └── .Rbuildignore /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /configure.win: -------------------------------------------------------------------------------- 1 | cp src/makevars.h.win src/makevars.h 2 | -------------------------------------------------------------------------------- /src/makevars.hpp: -------------------------------------------------------------------------------- 1 | unsigned char Makevars[] = { 0x00 }; 2 | -------------------------------------------------------------------------------- /src/makevars.h.win: -------------------------------------------------------------------------------- 1 | unsigned char Makevars[] = { 0x00 }; 2 | -------------------------------------------------------------------------------- /src/makevars.h.win64: -------------------------------------------------------------------------------- 1 | unsigned char Makevars[] = { 0x00 }; 2 | -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/R/sysdata.rda -------------------------------------------------------------------------------- /man-roxygen/visitId.R: -------------------------------------------------------------------------------- 1 | #' @param visitId Deprecated. Use \code{visit_name} 2 | -------------------------------------------------------------------------------- /data/vermont_dx.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/vermont_dx.rda -------------------------------------------------------------------------------- /man-roxygen/dotdotdot.R: -------------------------------------------------------------------------------- 1 | #' @param ... arguments passed on to other functions 2 | 3 | -------------------------------------------------------------------------------- /.aspell/icdwords.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/.aspell/icdwords.rds -------------------------------------------------------------------------------- /cleanup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -f config.* src/Makevars src/makevars.h makevars.h 4 | 5 | -------------------------------------------------------------------------------- /data/icd10_map_cc.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_cc.rda -------------------------------------------------------------------------------- /data/icd10_map_ccs.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_ccs.rda -------------------------------------------------------------------------------- /data/icd10cm2019.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10cm2019.rda -------------------------------------------------------------------------------- /data/icd9_majors.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_majors.rda -------------------------------------------------------------------------------- /data/icd9_map_ahrq.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_ahrq.rda -------------------------------------------------------------------------------- /data/icd9_map_cc.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_cc.rda -------------------------------------------------------------------------------- /data/icd9_map_elix.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_elix.rda -------------------------------------------------------------------------------- /vignettes/jsslogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/vignettes/jsslogo.jpg -------------------------------------------------------------------------------- /data/icd10_map_ahrq.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_ahrq.rda -------------------------------------------------------------------------------- /data/icd10_map_elix.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_elix.rda -------------------------------------------------------------------------------- /data/icd10_names_ccs.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_names_ccs.rda -------------------------------------------------------------------------------- /data/icd9cm2014_leaf.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9cm2014_leaf.rda -------------------------------------------------------------------------------- /data/icd_map_cc_hcc.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd_map_cc_hcc.rda -------------------------------------------------------------------------------- /man-roxygen/icd9df.R: -------------------------------------------------------------------------------- 1 | #' @param icd9df Deprecated. Use \code{x} to provide a data frame input 2 | -------------------------------------------------------------------------------- /tools/crash-cases/icd10.R: -------------------------------------------------------------------------------- 1 | library(icd) 2 | devnull <- comorbid_ahrq(uranium_pathology) 3 | 4 | -------------------------------------------------------------------------------- /data/icd10_map_ahrq_pcs.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_ahrq_pcs.rda -------------------------------------------------------------------------------- /data/icd10_map_charlson.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_charlson.rda -------------------------------------------------------------------------------- /data/icd10_map_pccc_dx.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_pccc_dx.rda -------------------------------------------------------------------------------- /data/icd10_map_pccc_pcs.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_pccc_pcs.rda -------------------------------------------------------------------------------- /data/icd10_sub_chapters.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_sub_chapters.rda -------------------------------------------------------------------------------- /data/icd9_map_charlson.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_charlson.rda -------------------------------------------------------------------------------- /data/icd9_map_multi_ccs.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_multi_ccs.rda -------------------------------------------------------------------------------- /data/icd9_map_pccc_dx.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_pccc_dx.rda -------------------------------------------------------------------------------- /data/icd9_map_pccc_pcs.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_pccc_pcs.rda -------------------------------------------------------------------------------- /data/icd9_map_quan_deyo.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_quan_deyo.rda -------------------------------------------------------------------------------- /data/icd9_map_quan_elix.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_quan_elix.rda -------------------------------------------------------------------------------- /data/icd9cm_hierarchy.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9cm_hierarchy.rda -------------------------------------------------------------------------------- /data/uranium_pathology.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/uranium_pathology.rda -------------------------------------------------------------------------------- /tools/travis-ccache.conf: -------------------------------------------------------------------------------- 1 | max_size = 5.0G 2 | sloppiness = include_file_ctime 3 | hash_dir = false 4 | -------------------------------------------------------------------------------- /benchmarks/lookup-fourth.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/benchmarks/lookup-fourth.rda -------------------------------------------------------------------------------- /benchmarks/rtf-fourth-out.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/benchmarks/rtf-fourth-out.rda -------------------------------------------------------------------------------- /data/icd10_map_quan_deyo.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_quan_deyo.rda -------------------------------------------------------------------------------- /data/icd10_map_quan_elix.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd10_map_quan_elix.rda -------------------------------------------------------------------------------- /data/icd9_map_single_ccs.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_map_single_ccs.rda -------------------------------------------------------------------------------- /data/icd9_names_multi_ccs.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_names_multi_ccs.rda -------------------------------------------------------------------------------- /data/icd9_names_single_ccs.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/data/icd9_names_single_ccs.rda -------------------------------------------------------------------------------- /man-roxygen/verbose.R: -------------------------------------------------------------------------------- 1 | #' @param verbose single logical value, defaults to \code{FALSE} in most functions. 2 | -------------------------------------------------------------------------------- /man/figures/README-example-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/man/figures/README-example-1.png -------------------------------------------------------------------------------- /tests/testthat/github133-b.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/tests/testthat/github133-b.rds -------------------------------------------------------------------------------- /vignettes/efficiency-prebuilt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/vignettes/efficiency-prebuilt.pdf -------------------------------------------------------------------------------- /man-roxygen/poaField.R: -------------------------------------------------------------------------------- 1 | #' @param poaField Deprecated. Use \code{poa_name} and the \code{filter_poa} 2 | #' family of functions. 3 | -------------------------------------------------------------------------------- /vignettes/country-lang-vers-prebuilt.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/vignettes/country-lang-vers-prebuilt.pdf -------------------------------------------------------------------------------- /man-roxygen/ccs-single.R: -------------------------------------------------------------------------------- 1 | #' @param single a logical value, if \code{TRUE} then use single level CCS, 2 | #' otherwise use multi level 3 | -------------------------------------------------------------------------------- /tools/appveyor-yaml-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ruby -ryaml -e "p YAML.load(STDIN.read)" <"${ICD_HOME?}/appveyor.yml" >/dev/null 4 | -------------------------------------------------------------------------------- /tools/travis-yaml-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ruby -ryaml -e "p YAML.load(STDIN.read)" <"${ICD_HOME:-.}/.travis.yml" >/dev/null 4 | -------------------------------------------------------------------------------- /man-roxygen/lang.R: -------------------------------------------------------------------------------- 1 | #' @param lang Language string, e.g., \code{en}, \code{fr}, \code{nl} or others 2 | #' that may be supported in the future. 3 | -------------------------------------------------------------------------------- /src/Makevars.in: -------------------------------------------------------------------------------- 1 | # @configure_input@ 2 | CXX_STD=CXX14 3 | PKG_CXXFLAGS=@ICD_SHUTUP_FLAG@ @ICD_OPENMP_FLAG@ 4 | PKG_LIBS=@ICD_OPENMP_FLAG@ 5 | @ICD_STRIP@ 6 | -------------------------------------------------------------------------------- /benchmarks/icd-JSS3447-replication/medicalrisk_1.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/benchmarks/icd-JSS3447-replication/medicalrisk_1.2.tar.gz -------------------------------------------------------------------------------- /benchmarks/icd-JSS3447-replication/comorbidity_0.1.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jackwasey/icd/HEAD/benchmarks/icd-JSS3447-replication/comorbidity_0.1.1.tar.gz -------------------------------------------------------------------------------- /man-roxygen/invert.R: -------------------------------------------------------------------------------- 1 | #' @param invert Single logical value. Returns the inverse of the result. E.g. 2 | #' if seeking valid ICD-9 codes, the invalid ones are returned. 3 | -------------------------------------------------------------------------------- /.Rinstignore: -------------------------------------------------------------------------------- 1 | ^COPYING$ 2 | ^doc\/efficiency\.pdf$ 3 | ^doc\/country-lang-vers\.pdf$ 4 | ^vignettes\/efficiency-prebuilt\.pdf$ 5 | ^vignettes\/country-lang-vers-prebuilt\.pdf$ 6 | -------------------------------------------------------------------------------- /.covrignore: -------------------------------------------------------------------------------- 1 | inst/include/icd_RcppExports.h 2 | src/RcppExports.cpp 3 | R/RcppExports.R 4 | R/parse-icd10cm-xml.R 5 | R/fuzz.R 6 | R/*_alt.R 7 | src/*_alt*.cpp 8 | src/*.h 9 | -------------------------------------------------------------------------------- /man-roxygen/sep.R: -------------------------------------------------------------------------------- 1 | #' @param sep character separator, usually \sQuote{} or \sQuote{.} corresponding 2 | #' to \sQuote{short} or \sQuote{decimal} ICD-9 codes, respectively. 3 | -------------------------------------------------------------------------------- /man-roxygen/whitespace_ok.R: -------------------------------------------------------------------------------- 1 | #' @param whitespace_ok Single logical, if \code{TRUE}, the default, matches for 2 | #' ICD codes will accept leading and trailing white space. 3 | -------------------------------------------------------------------------------- /man-roxygen/toParent.R: -------------------------------------------------------------------------------- 1 | #' @param toParent single logical value which, if \code{TRUE}, will step up the 2 | #' hierarchy to four or three digit descriptions of groups of codes. 3 | -------------------------------------------------------------------------------- /src/cutil.h: -------------------------------------------------------------------------------- 1 | #ifndef CUTIL_H_ 2 | #define CUTIL_H_ 3 | 4 | #include 5 | 6 | SEXP getRListOrDfElement(SEXP list, const char *str); 7 | 8 | #endif /* CUTIL_H_ */ 9 | -------------------------------------------------------------------------------- /src/Makevars.win: -------------------------------------------------------------------------------- 1 | CXX_STD=CXX14 2 | # no openmp, since thread model is different, and is likely to be much slower, 3 | # although perhaps Eigen is clever enough to account for this. 4 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.dll 3 | *.dylib 4 | *.gcda 5 | *.gch 6 | *.gcno 7 | *.gcov 8 | *.o 9 | *.out 10 | *.so 11 | .cproject 12 | .settings/ 13 | config.h 14 | Makevars 15 | prof 16 | -------------------------------------------------------------------------------- /man-roxygen/warn.R: -------------------------------------------------------------------------------- 1 | #' @param warn single logical value, if \code{TRUE}, give warnings when 2 | #' there is discrepancy between \code{defined} being \code{TRUE} yet data 3 | #' containing undefined codes. 4 | -------------------------------------------------------------------------------- /src/fastIntToString.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FASTINTTOSTRING_H_ 2 | #define FASTINTTOSTRING_H_ 3 | 4 | #include "icd_types.hpp" 5 | CV fastIntToStringRcpp(Rcpp::IntegerVector x); 6 | 7 | #endif /* FASTINTTOSTRING_H_ */ 8 | -------------------------------------------------------------------------------- /man-roxygen/pc.R: -------------------------------------------------------------------------------- 1 | #' @param pc Logical, if \code{TRUE}, will return names of procedure code data 2 | #' frames. Default is \code{FALSE} which will return the names of the 3 | #' diagnostic code data frames. 4 | 5 | -------------------------------------------------------------------------------- /tools/crash-cases/reduce-icd10.R: -------------------------------------------------------------------------------- 1 | library(icd) 2 | redc <- icd:::icd10_comorbid_reduce(uranium_pathology, icd10_map_ahrq, visit_name = "case", icd_name = "icd10", short_code = FALSE, short_map = TRUE, return_df = FALSE) 3 | -------------------------------------------------------------------------------- /.gitconfig: -------------------------------------------------------------------------------- 1 | [diff "png"] 2 | textconv = identify -quiet -format "%#" 3 | [diff "pdf"] 4 | # or consider pdftotext 5 | textconv = identify -quiet -format "%#" 6 | [diff "nodiff"] 7 | command = /bin/true 8 | 9 | -------------------------------------------------------------------------------- /src/.clang-tidy: -------------------------------------------------------------------------------- 1 | UseColor: true 2 | HeaderFilterRegex: '.*' 3 | Checks: 'misc-*,clang-diagnostic-*,clang-analyzer-*,modernize-*,openmp-*,performance-*,readability-*,bugprone-*,-readability-identifier-naming' 4 | FormatStyle: file 5 | -------------------------------------------------------------------------------- /man-roxygen/save_pkg_data.R: -------------------------------------------------------------------------------- 1 | #' @param save_pkg_data single logical value, if \code{TRUE} will save the 2 | #' generated data into the package data directory. This is intended only for 3 | #' package maintenance, not the end user. 4 | -------------------------------------------------------------------------------- /benchmarks/bench-charlson.R: -------------------------------------------------------------------------------- 1 | #' \dontrun{ 2 | #' # let's do five million patients and benchmark 3 | #' big <- icd:::generate_random_pts(5E6) 4 | #' microbenchmark::microbenchark( 5 | #' charlson(big), 6 | #' times = 5 7 | #' ) 8 | #' } 9 | -------------------------------------------------------------------------------- /man-roxygen/short_map.R: -------------------------------------------------------------------------------- 1 | #' @param short_map Same as short, but applied to \code{map} instead of the data 2 | #' frame of ICD codes, \code{x}. All the codes in a mapping should be of the 3 | #' same type, i.e. short or decimal. 4 | 5 | -------------------------------------------------------------------------------- /benchmarks/bench-expand.R: -------------------------------------------------------------------------------- 1 | microbenchmark::microbenchmark( 2 | icd9_expand_range_worker_alt_base("100", "114", icd9_short_n, TRUE, TRUE, TRUE), 3 | icd9_expand_range_worker("100", "114", icd9_short_n, TRUE, TRUE, TRUE), 4 | times = 5 5 | ) 6 | -------------------------------------------------------------------------------- /man-roxygen/short_code.R: -------------------------------------------------------------------------------- 1 | #' @param short_code single logical value which determines whether the ICD-9 2 | #' code provided is in short (\code{TRUE}) or decimal (\code{FALSE}) form. 3 | #' Where reasonable, this is guessed from the input data. 4 | -------------------------------------------------------------------------------- /man-roxygen/abbrev_names.R: -------------------------------------------------------------------------------- 1 | #' @param abbrev_names single logical value that defaults to \code{TRUE}, in 2 | #' which case the shorter human-readable names stored in e.g. 3 | #' \code{ahrqComorbidNamesAbbrev} are applied to the data frame column names. 4 | -------------------------------------------------------------------------------- /man-roxygen/hierarchy.R: -------------------------------------------------------------------------------- 1 | #' @param hierarchy single logical value that defaults to \code{TRUE}, in which 2 | #' case the hierarchy defined for the mapping is applied. E.g. in Elixhauser, 3 | #' you can't have uncomplicated and complicated diabetes both flagged. 4 | -------------------------------------------------------------------------------- /man-roxygen/offline.R: -------------------------------------------------------------------------------- 1 | #' @param offline single logical, if \code{TRUE} then don't pull the file from 2 | #' internet, only return path and file name if the file already exists in the 3 | #' raw data directory. This is helpful for testing without using the internet. 4 | -------------------------------------------------------------------------------- /man-roxygen/scoring-system.R: -------------------------------------------------------------------------------- 1 | #' @param scoring_system One of \code{original}, \code{charlson}, or 2 | #' \code{quan}. The first two will give the original Charlson weights for each 3 | #' comorbidity, whereas \code{quan} uses the updated weights from Quan 2011. 4 | 5 | -------------------------------------------------------------------------------- /tools/build-full.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | IFS=$'\n\t' 4 | 5 | ICD_HOME="${ICD_HOME:-${HOME}/icd}" 6 | 7 | R CMD build \ 8 | --log \ 9 | --resave-data=xz \ 10 | --compact-vignettes=gs+qpdf \ 11 | "$@" \ 12 | "${ICD_HOME}" 13 | 14 | -------------------------------------------------------------------------------- /tools/gdb_fun.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # http://redsymbol.net/articles/unofficial-bash-strict-mode/ 4 | set -eu 5 | IFS=$'\n\t' 6 | 7 | MAKEFLAGS="CXXFLAGS=-O0 -g CCFLAGS=-O0 -g CXX=G++ CC=gcc" R CMD INSTALL --vanilla ~/icd9 8 | R -d gdb -e "{$1:-icd:::runSetInt();}" 9 | -------------------------------------------------------------------------------- /man-roxygen/leadingZeroes.R: -------------------------------------------------------------------------------- 1 | #' @param leadingZeroes logical whether to fill out major part with zeroes, or 2 | #' just truncate to the left. If E code, there is no valid code since 3 | #' E800-E999 is defined. V codes could be V0x or Vxx, and so could be zero 4 | #' padded. 5 | -------------------------------------------------------------------------------- /man-roxygen/poa_name.R: -------------------------------------------------------------------------------- 1 | #' @param poa_name The name of column in the data frame which contains the 2 | #' Present On Arrival (POA) flag. The flag itself is a single character, 3 | #' typically one of \sQuote{Y}, \sQuote{N}, \sQuote{E}, \sQuote{X}, 4 | #' \sQuote{U}, or empty. 5 | 6 | -------------------------------------------------------------------------------- /man-roxygen/isShort.R: -------------------------------------------------------------------------------- 1 | #' @param isShort Deprecated. Single logical value which determines whether the 2 | #' ICD-9 code provided is in short (\code{TRUE}) or decimal (\code{FALSE}) 3 | #' form. Where reasonable, this is guessed from the input data. Use 4 | #' \code{short_code} instead. 5 | -------------------------------------------------------------------------------- /man-roxygen/ver.R: -------------------------------------------------------------------------------- 1 | #' @param ver Character vector of length one: the version of ICD-10-CM to use, 2 | #' corresponding to the suffix of the \code{data.frame} name, e.g., for 2019 3 | #' ICD-10-CM, use \code{"icd10cm2019"} for Dutch 2014 ICD-CM translations, use 4 | #' \code{"icd10cm2014_nl"} 5 | -------------------------------------------------------------------------------- /tests/testthat/test-icd10be.R: -------------------------------------------------------------------------------- 1 | context("ICD-10-BE") 2 | 3 | test_that("basic Belgian", { 4 | skip_missing_dat("icd10be2014") 5 | skip_missing_dat("icd10be2017") 6 | expect_true(inherits(get_icd10be2014()$code, "icd10be")) 7 | expect_true(inherits(get_icd10be2017()$code, "icd10be")) 8 | }) 9 | -------------------------------------------------------------------------------- /inst/COPYRIGHTS: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | 3 | Files: * 4 | Copyright: 2014-2020 Jack O Wasey 5 | License: GPL-3 6 | 7 | Files: m4/openmp.m4 8 | Copyright: 2001-2012 Free Software Foundation, Inc. 9 | Copyright: 2015-2018 R Core Team 10 | 11 | -------------------------------------------------------------------------------- /man-roxygen/mjr.R: -------------------------------------------------------------------------------- 1 | #' @param major character vector of 'major' part of ICD-9 codes, i.e. that part 2 | #' which falls before the decimal point, in decimal notation. (In five digit 3 | #' notation, the 'major' part is be the first three characters (with leading 4 | #' zeroes), and includes V or E prefix. 5 | -------------------------------------------------------------------------------- /tests/testthat/test-filter-icd10.R: -------------------------------------------------------------------------------- 1 | context("filtering on ICD-10 validity") 2 | 3 | pts <- icd10_all_ahrq 4 | pts[1, "icd10_code"] <- "invalid" 5 | 6 | test_that("filter an invalid row", { 7 | expect_warning(res <- icd10_filter_invalid(pts), regexp = NA) 8 | expect_is(res, "data.frame") 9 | }) 10 | -------------------------------------------------------------------------------- /tools/format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -x 3 | cd "${ICD_HOME:-$HOME/icd/src}" || { echo "failed to cd to icd home" >&2; exit 1; } 4 | find . -name '*.c' -o -name '*.h' -o \( -name '*.cpp' -a -not -name 'RcppExports.cpp' \) | 5 | while read -r f; do 6 | xargs clang-format-9 "$f"; 7 | done 8 | -------------------------------------------------------------------------------- /src/attr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ATTR_H_ 2 | #define ATTR_H_ 3 | 4 | #include "icd_types.hpp" 5 | 6 | void setDecimalDiag(Rcpp::RObject &x, bool value); 7 | void setDecimalDiag(CV &x, bool); 8 | void setShortDiag(Rcpp::RObject &x, bool value); 9 | void setShortDiag(CV &x, bool); 10 | 11 | #endif /* ATTR_H_ */ 12 | -------------------------------------------------------------------------------- /tools/build-quick.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | IFS=$'\n\t' 4 | 5 | # quickly build the pacakge, and put it in the current directory 6 | R CMD build \ 7 | --log \ 8 | --no-build-vignettes \ 9 | --no-manual \ 10 | --no-resave-data \ 11 | "$@" \ 12 | "${ICD_HOME?}" 13 | 14 | -------------------------------------------------------------------------------- /man/icd9_sub_chapters.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \name{icd9_sub_chapters} 4 | \alias{icd9_sub_chapters} 5 | \title{ICD-9 sub-chapters} 6 | \description{ 7 | ICD-9 sub-chapters 8 | } 9 | \seealso{ 10 | \code{\link{icd9_chapters}} 11 | } 12 | -------------------------------------------------------------------------------- /benchmarks/bench-parse-rtf.R: -------------------------------------------------------------------------------- 1 | library(profr) 2 | 3 | prf_rtf <- profr::profr(rtf_parse_year(year = "2011")) 4 | print(head(prf_rtf)) 5 | 6 | Rprof(filename = "/tmp/rtf.txt", interval = 0.001, line.profiling = TRUE) 7 | rtf_parse_year(year = "2011") 8 | Rprof(NULL) 9 | summaryRprof("/tmp/rtf.txt", lines = "show") 10 | -------------------------------------------------------------------------------- /man-roxygen/return_df.R: -------------------------------------------------------------------------------- 1 | #' @param return_df single logical value, if \code{TRUE}, return 'tidy' data, 2 | #' i.e., the result is a data frame with the first column being the 3 | #' \code{visit_id}, and the second being the count. If \code{visit_id} was a 4 | #' factor or named differently in the input, this is preserved. 5 | -------------------------------------------------------------------------------- /src/test-runner.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Please do not edit this file -- it ensures that your package will export a 3 | * 'run_testthat_tests()' C routine that can be used to run the Catch unit tests 4 | * available in your package. 5 | */ 6 | #ifdef ICD_CATCH 7 | #define TESTTHAT_TEST_RUNNER 8 | #include 9 | #endif 10 | -------------------------------------------------------------------------------- /src/convert10.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CONVERT10_H_ 2 | #define CONVERT10_H_ 3 | 4 | #include 5 | 6 | Rcpp::List icd10ShortToParts(const Rcpp::CharacterVector & x, const Rcpp::String & mnrEmpty); 7 | Rcpp::List icd10DecimalToParts(const Rcpp::CharacterVector & x, const Rcpp::String & mnrEmpty); 8 | 9 | #endif /* CONVERT10_H_ */ 10 | -------------------------------------------------------------------------------- /tests/testthat/test-explain-fr.R: -------------------------------------------------------------------------------- 1 | context("explain France codes") 2 | 3 | test_that("can explain some codes", { 4 | skip_missing_icd10fr() 5 | expect_false(is.null(explain_code(as.icd10fr("A00")))) 6 | expect_false(is.null(explain_code(as.icd10fr("Z998")))) 7 | expect_identical(explain_code(as.icd10fr("B04")), "Monkeypox") 8 | }) 9 | -------------------------------------------------------------------------------- /tools/crash-cases/eigen.R: -------------------------------------------------------------------------------- 1 | library(icd) 2 | library(testthat) 3 | library(devtools) 4 | library(magrittr) 5 | library(R.cache) 6 | ten_million_random_pts <- loadCache(key = list("ten_million_random_pts"), suffix = "icd.Rcache") 7 | devnull2 <- replicate(100L, devnull <- icd_comorbid_ahrq(ten_million_random_pts, preclean = FALSE)) 8 | 9 | -------------------------------------------------------------------------------- /man-roxygen/dx.R: -------------------------------------------------------------------------------- 1 | #' @param dx Single logical value, if \code{TRUE} the default, diagnostic codes will be retrieved and processed. If \code{FALSE}, procedure codes will be used. Note that most ICD-10 schemes around the world do not add procedure codes. The US uses them extensively, and these form the basis of the Belgian version of ICD-10. 2 | 3 | -------------------------------------------------------------------------------- /man/get_icd10cm2014.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2014} 5 | \alias{get_icd10cm2014} 6 | \title{ICD-10-CM 2014} 7 | \description{ 8 | ICD-10-CM 2014 9 | } 10 | \seealso{ 11 | \code{\link{icd10cm2019}} 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/get_icd10cm2015.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2015} 5 | \alias{get_icd10cm2015} 6 | \title{ICD-10-CM 2015} 7 | \description{ 8 | ICD-10-CM 2015 9 | } 10 | \seealso{ 11 | \code{\link{icd10cm2019}} 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/get_icd10cm2016.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2016} 5 | \alias{get_icd10cm2016} 6 | \title{ICD-10-CM 2016} 7 | \description{ 8 | ICD-10-CM 2016 9 | } 10 | \seealso{ 11 | \code{\link{icd10cm2019}} 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/get_icd10cm2017.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2017} 5 | \alias{get_icd10cm2017} 6 | \title{ICD-10-CM 2017} 7 | \description{ 8 | ICD-10-CM 2017 9 | } 10 | \seealso{ 11 | \code{\link{icd10cm2019}} 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/get_icd10cm2018.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2018} 5 | \alias{get_icd10cm2018} 6 | \title{ICD-10-CM 2018} 7 | \description{ 8 | ICD-10-CM 2018 9 | } 10 | \seealso{ 11 | \code{\link{icd10cm2019}} 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man/get_icd10cm2019.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2019} 5 | \alias{get_icd10cm2019} 6 | \title{ICD-10-CM 2019} 7 | \description{ 8 | ICD-10-CM 2019 9 | } 10 | \seealso{ 11 | \code{\link{icd10cm2019}} 12 | } 13 | \keyword{datasets} 14 | -------------------------------------------------------------------------------- /man-roxygen/stringsAsFactors.R: -------------------------------------------------------------------------------- 1 | #' @param stringsAsFactors Single logical value, describing whether the resulting data frame should have strings, e.g. 2 | #' \code{visit_id} converted to factor. Default is to follow the current session option. This is identical to the 3 | #' argument used in, among other base functions \code{as.data.frame}. 4 | 5 | -------------------------------------------------------------------------------- /benchmarks/bench-rbind-with-empty.R: -------------------------------------------------------------------------------- 1 | nrow <- 1e5 2 | a <- matrix(rnorm(nrow * 30) < 0.5, nrow = nrow, ncol = 30) 3 | identical(rbind(a, matrix(FALSE, nrow = 1e5, ncol = 30)), icd:::rbind_with_empty(a, nrow)) 4 | microbenchmark::microbenchmark( 5 | rbind(a, matrix(FALSE, nrow = 1e5, ncol = 30)), 6 | icd:::rbind_with_empty(a, nrow), 7 | times = 5 8 | ) 9 | -------------------------------------------------------------------------------- /man-roxygen/return.df.R: -------------------------------------------------------------------------------- 1 | #' @param return.df Deprecated. Use \code{return_df} instead. Single logical 2 | #' value, if \code{TRUE}, return the result as a data frame with the first 3 | #' column being the \code{visitId}, and the second being the count. If 4 | #' \code{visitId} was a factor or named differently in the input, this is 5 | #' preserved. 6 | -------------------------------------------------------------------------------- /tests/testthat/test-spell.R: -------------------------------------------------------------------------------- 1 | context("dictionary compiles for spelling check") 2 | 3 | test_that("dictionary created", { 4 | skip_on_cran() 5 | skip_on_appveyor() 6 | skip_on_travis() 7 | words <- .generate_spelling(save_pkg_data = FALSE) 8 | expect_character(words) 9 | expect_true(file.exists(system.file("WORDLIST", package = "icd"))) 10 | }) 11 | -------------------------------------------------------------------------------- /tools/rprof-one-cmd.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | IFS=$'\n\t' 4 | 5 | ICD_HOME=$HOME/icd 6 | cd "$ICD_HOME}" || { echo "cannot cd to ${ICD_HOME}" >&2; exit 1; } 7 | Rscript --with-default-packages=icd \ 8 | -e "pts<-icd:::generate_random_pts(1e3); 9 | Rprof(\"profr.out\"); 10 | x <- icd_comorbid_quan_deyo(pts); 11 | Rprof(NULL)" 12 | -------------------------------------------------------------------------------- /man-roxygen/mnr.R: -------------------------------------------------------------------------------- 1 | #' @param minor character vector of 'minor' part of ICD-9 codes, i.e. that part 2 | #' which falls after the decimal point, in decimal notation. (In 'short' five 3 | #' digit notation, the 'major' part is the first three characters including 4 | #' leading zeroes which may be inferred; the last two characters represent the 5 | #' 'minor' part.) 6 | -------------------------------------------------------------------------------- /.lintr: -------------------------------------------------------------------------------- 1 | linters: with_defaults(object_name_linter = NULL, object_usage_linter = NULL, line_length_linter(90), object_length_linter(length = 36L), undesirable_function_linter("sapply"), trailing_whitespace_linter = NULL) 2 | exclusions: c(list("R/z-deprecated.R", "R/RcppExports.R", "R/benchmark.R"), list.files(path = "inst/doc", recursive = TRUE, full.names = TRUE)) 3 | cache: TRUE 4 | -------------------------------------------------------------------------------- /man/icd9cm2014_leaf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{icd9cm2014_leaf} 5 | \alias{icd9cm2014_leaf} 6 | \title{The final ICD-9-CM list of leaf (\sQuote{billable}) codes} 7 | \description{ 8 | Other years are available from \code{\link{get_icd9cm2013_leaf}}, etc.. 9 | } 10 | \keyword{datasets} 11 | -------------------------------------------------------------------------------- /man-roxygen/icd9-any.R: -------------------------------------------------------------------------------- 1 | #' @param <% if (exists("icd9AnyName")) cat(icd9AnyName) else cat("icd9") %> is 2 | #' a character vector or factor of ICD-9 codes. If fewer than five characters 3 | #' is given in a code, then the digits are greedily assigned to hundreds, then 4 | #' tens, then units, before the decimal parts. E.g., \code{10} becomes 5 | #' \code{010}, not \code{0010} or \code{00010}. 6 | -------------------------------------------------------------------------------- /man-roxygen/icd9-decimal.R: -------------------------------------------------------------------------------- 1 | #' @param <% if (exists("icd9DecimalName")) cat(icd9ShortName) else 2 | #' cat("icd9Decimal") %> character vector of ICD-9 codes. If fewer than five 3 | #' characters is given in a code, then the digits are greedily assigned to 4 | #' hundreds, then tens, then units, before the decimal parts. E.g., \code{10} 5 | #' becomes \code{010}, not \code{0010} or \code{00010}. 6 | -------------------------------------------------------------------------------- /man-roxygen/icd9-short.R: -------------------------------------------------------------------------------- 1 | #' @param <% if (exists("icd9ShortName")) cat(icd9ShortName) else cat("icd9Short") %> 2 | #' is a character vector of ICD-9 codes. If fewer than five 3 | #' characters is given in a code, then the digits are greedily assigned to 4 | #' hundreds, then tens, then units, before the decimal parts. E.g., \code{10} 5 | #' becomes \code{010}, not \code{0010} or \code{00010}. 6 | -------------------------------------------------------------------------------- /tools/env/rhub: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #shellcheck disable=SC2034 3 | # 4 | # 5 | # 6 | #MAKEFLAGS="CXXFLAGS=-Wno-unused-parameter\\ -Wno-unused-variable\\ -Wno-ignored-attributes\\ -Wno-cast-function-type\\ -Wno-unknown-warning-option\\ -Wno-unknown-pragma" 7 | _R_CHECK_ASCII_DATA_=FALSE 8 | _R_CHECK_DOC_SIZES2_=FALSE 9 | _R_CHECK_DOC_SIZES_=FALSE 10 | MAKEFLAGS="CXXFLAGS=-w CXX11FLAGS=-w" 11 | -------------------------------------------------------------------------------- /tools/install-full.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2012 3 | set -eu 4 | IFS=$'\n\t' 5 | "${ICD_HOME:-$HOME/icd}"/tools/build.sh 6 | MAKEFLAGS=-j$(getconf _NPROCESSORS_ONLN) \ 7 | R CMD INSTALL \ 8 | --no-clean-on-error \ 9 | --debug \ 10 | --install-tests \ 11 | --data-compress=none \ 12 | --no-resave_data \ 13 | --strip \ 14 | "$(ls -t icd_*.tar.gz | head -1)" 15 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | !country-lang-vers-prebuilt.pdf 2 | !efficiency-prebuilt.pdf 3 | *.R 4 | *.aux 5 | *.bbl 6 | *.blg 7 | *.dvi 8 | *.fdb_latexmk 9 | *.fls 10 | *.html 11 | *.knit.md 12 | *.log 13 | *.out 14 | *.pdf 15 | *.synctex.gz 16 | *.tex 17 | *.utf8.md 18 | *_files/ 19 | *cache* 20 | .build.timestamp 21 | country-lang-vers*_files/* 22 | efficiency*_files/* 23 | icd.bib 24 | test*.Rmd 25 | test2 26 | -------------------------------------------------------------------------------- /man/get_icd10be2017.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10be2017} 5 | \alias{get_icd10be2017} 6 | \title{ICD-10-BE 2017} 7 | \description{ 8 | ICD-10-BE 2017 9 | } 10 | \seealso{ 11 | \code{\link{get_icd10be2014}} \code{\link{get_icd10be2014_pc}} 12 | \code{\link{get_icd10be2017_pc}} 13 | } 14 | \keyword{datasets} 15 | -------------------------------------------------------------------------------- /src/is.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IS_H_ 2 | #define IS_H_ 3 | #include "icd_types.hpp" // for VecStr 4 | 5 | bool icd9IsASingleV(const char *s); 6 | bool icd9IsASingleE(const char *s); 7 | bool icd9IsASingleVE(const char *s); 8 | std::vector icd9_is_n_rcpp(const VecStr &sv); 9 | std::vector icd9_is_v_rcpp(const VecStr &sv); 10 | std::vector icd9_is_e_rcpp(const VecStr &sv); 11 | 12 | #endif /* IS_H_ */ 13 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: 2 | layout: "header, diff, tree, changes" 3 | behavior: default 4 | require_changes: true # only post if coverage changes 5 | branches: null 6 | flags: null 7 | paths: null 8 | 9 | coverage: 10 | status: 11 | project: 12 | default: 13 | target: auto 14 | threshold: 1% 15 | patch: 16 | default: 17 | target: auto 18 | threshold: 1% 19 | -------------------------------------------------------------------------------- /src/manip.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MANIP_H_ 2 | #define MANIP_H_ 3 | 4 | #include "icd_types.hpp" 5 | 6 | CV icd9AddLeadingZeroes(const CV& icd9, bool isShort); 7 | CV icd9AddLeadingZeroesShort(CV icd9Short); 8 | Rcpp::String icd9AddLeadingZeroesMajorSingle(const Rcpp::String& major); 9 | std::string icd9AddLeadingZeroesMajorSingleStd(std::string m); 10 | CV icd9AddLeadingZeroesMajor(const CV& mjr); 11 | 12 | #endif /* MANIP_H_ */ 13 | -------------------------------------------------------------------------------- /src/mapplus.hpp: -------------------------------------------------------------------------------- 1 | #include "local.hpp" 2 | #include "relevant.hpp" 3 | using namespace Rcpp; 4 | 5 | #ifndef MAPPLUS_H_ 6 | #define MAPPLUS_H_ 7 | 8 | class MapPlus { 9 | public: 10 | MapPlus(const List &icd9Mapping, const Relevant &rh); 11 | void buildMatrix(); 12 | List map; // consider ListOf 13 | DenseMap mat; 14 | R_xlen_t rows() { return mat.rows(); } 15 | }; 16 | 17 | #endif // MAPPLUS_H 18 | -------------------------------------------------------------------------------- /tests/testthat/test-build-maps-icd9-kids-charl.R: -------------------------------------------------------------------------------- 1 | context("ICD-9 map children all present") 2 | 3 | skip_slow("Skipping slow checking of ICD-9 comorbidity map children (charl)") 4 | 5 | test_that("Quan Charlson children same as saved", { 6 | for (i in icd9_map_quan_deyo) { 7 | expect_equal_no_class_order( 8 | children.icd9(i, defined = FALSE, short_code = TRUE), 9 | sort.icd9(i) 10 | ) 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /tools/mk/travis-debug.mk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env make 2 | icd_debug_flags := -O0 -g3 3 | @echo adding $(icd_debug_flags) to C, Fortran and C++ flags 4 | CXXFLAGS += $(icd_debug_flags) 5 | CXX11FLAGS += $(icd_debug_flags) 6 | CXX14FLAGS += $(icd_debug_flags) 7 | CXX17FLAGS += $(icd_debug_flags) 8 | CXX20FLAGS += $(icd_debug_flags) 9 | CFLAGS += $(icd_debug_flags) 10 | FCFLAGS += $(icd_debug_flags) 11 | F77FLAGS += $(icd_debug_flags) 12 | -------------------------------------------------------------------------------- /man-roxygen/parse-template.R: -------------------------------------------------------------------------------- 1 | #' @param condense Deprecated. The map is not condensed by default. If required, 2 | #' it can reduced to a smaller set of codes using \code{icd_condense}. 3 | #' @param save_pkg_data logical whether to save the result in the source tree. 4 | #' Defaults to \code{FALSE}. 5 | #' @return invisibly returns the list of vectors, where a co-morbidity name is 6 | #' associated with a character vector of ICD-9 codes. 7 | -------------------------------------------------------------------------------- /vignettes/gplv3.bib: -------------------------------------------------------------------------------- 1 | @misc{gplv3, 2 | title = {GNU General Public License}, 3 | author = "{Free Software Foundation}", 4 | version = {3}, 5 | shorthand = {GPL}, 6 | organization = {Free Software Foundation}, 7 | url = {http://www.gnu.org/licenses/gpl.html}, 8 | pagination = {section}, 9 | language = {english}, 10 | date = {2007-06-29}, 11 | year = {2007} 12 | } 13 | -------------------------------------------------------------------------------- /data-raw/.gitignore: -------------------------------------------------------------------------------- 1 | .~lock.Dtab12.rtf# 2 | Dtab10.RTF 3 | Pathology_Office2007.accdb 4 | Pathology_Office2007.laccdb 5 | Tabular.xml 6 | VTINP13.TXT 7 | all-covariates.xls 8 | allvalid2011%20%28detailed%20titles%20headings%29.txt 9 | allvalid2011%20(detailed%20titles%20headings).txt 10 | ccs_dx_icd10cm_2018_1.csv 11 | icd10*_order_201*.txt 12 | icd10.txt 13 | icd10cdc.txt 14 | icd10cm_codes_2016.txt 15 | pc_icd10pcs_2018.csv 16 | ~$Dtab12.rtf 17 | -------------------------------------------------------------------------------- /man-roxygen/return_binary.R: -------------------------------------------------------------------------------- 1 | #' @param return_binary Single logical value, if \code{TRUE}, the returned 2 | #' \code{matrix} or \code{data.frame} will be composed of \code{1} and 3 | #' \code{0}, instead of \code{TRUE} and \code{FALSE}, respectively. This 4 | #' conversion can also be done by the internal functions 5 | #' \code{icd:::logical_to_binary} and \code{icd:::binary_to_logical}, or using 6 | #' other tools, e.g. \code{apply(x, 2, as.integer)} 7 | -------------------------------------------------------------------------------- /man/get_icd10be2014_pc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10be2014_pc} 5 | \alias{get_icd10be2014_pc} 6 | \title{ICD-10-BE 2014 procedure codes} 7 | \description{ 8 | ICD-10-BE 2014 procedure codes 9 | } 10 | \seealso{ 11 | \code{\link{get_icd10be2014}} \code{\link{get_icd10be2017}} 12 | \code{\link{get_icd10be2017_pc}} 13 | } 14 | \keyword{datasets} 15 | -------------------------------------------------------------------------------- /man/get_icd10be2017_pc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10be2017_pc} 5 | \alias{get_icd10be2017_pc} 6 | \title{ICD-10-BE 2017 procedure codes} 7 | \description{ 8 | ICD-10-BE 2017 procedure codes 9 | } 10 | \seealso{ 11 | \code{\link{get_icd10be2014}} \code{\link{get_icd10be2014_pc}} 12 | \code{\link{get_icd10be2017}} 13 | } 14 | \keyword{datasets} 15 | -------------------------------------------------------------------------------- /man/get_icd10who2016.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10who2016} 5 | \alias{get_icd10who2016} 6 | \title{2016 WHO ICD-10 data} 7 | \source{ 8 | \url{http://www.who.int} 9 | } 10 | \description{ 11 | This data must be downloaded on a per-user basis. A prompt is given when the 12 | data is first attempted to be accessed. 13 | } 14 | \keyword{datasets} 15 | -------------------------------------------------------------------------------- /man-roxygen/poa.R: -------------------------------------------------------------------------------- 1 | #' @param poa single character value, being one of \code{Yes}, \code{No}, 2 | #' \code{NotYes}, and \code{NotNo}, indicating whether to account for 3 | #' comorbidities flagged as present-on-arrival. This is not a simple flag, 4 | #' because many codes are exempt, unspecified, or unknown. The intermediate 5 | #' codes, such as \sQuote{exempt}, \sQuote{unknown} and \code{NA} mean that 6 | #' \sQuote{yes} is not the same as \sQuote{not no}. 7 | -------------------------------------------------------------------------------- /man/poa_choices.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/comorbid.R 3 | \docType{data} 4 | \name{poa_choices} 5 | \alias{poa_choices} 6 | \title{Present-on-admission flags} 7 | \format{ 8 | An object of class \code{character} of length 4. 9 | } 10 | \usage{ 11 | poa_choices 12 | } 13 | \description{ 14 | See \link{filter_poa} for more details. 15 | } 16 | \examples{ 17 | poa_choices 18 | } 19 | \keyword{character} 20 | -------------------------------------------------------------------------------- /man/cr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/comorbid.R 3 | \name{cr} 4 | \alias{cr} 5 | \title{sequence columns of comorbidities} 6 | \usage{ 7 | cr(x) 8 | } 9 | \arguments{ 10 | \item{x}{matrix or data.frame of comorbidities} 11 | } 12 | \description{ 13 | Get sequence of column indices of comorbidity data frame, which differ 14 | between tidy data frames and clean, row-named matrices 15 | } 16 | \keyword{internal} 17 | -------------------------------------------------------------------------------- /man/get_cim10fr2019.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bindings.R 3 | \name{get_cim10fr2019} 4 | \alias{get_cim10fr2019} 5 | \title{Localised synonym for \code{\link{get_icd10fr2019}}, with French column names} 6 | \usage{ 7 | get_cim10fr2019() 8 | } 9 | \description{ 10 | Localised synonym for \code{\link{get_icd10fr2019}}, with French column names 11 | } 12 | \seealso{ 13 | \code{\link{get_icd10fr2019}} 14 | } 15 | -------------------------------------------------------------------------------- /man/get_icd10who2008fr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10who2008fr} 5 | \alias{get_icd10who2008fr} 6 | \title{2008 WHO ICD-10 data in French} 7 | \source{ 8 | \url{http://www.who.int} 9 | } 10 | \description{ 11 | This data must be downloaded on a per-user basis. A prompt is given when the 12 | data is first attempted to be accessed. 13 | } 14 | \keyword{datasets} 15 | -------------------------------------------------------------------------------- /man-roxygen/onlyBillable.R: -------------------------------------------------------------------------------- 1 | #' @param onlyBillable single logical value, if \code{TRUE}, describes the input 2 | #' data, stating that it only contains billable codes. Usually, the function 3 | #' will try to guess this, but if you know in advance what they should be, the 4 | #' functions can optionally warn if this is incorrect, and save some 5 | #' computation time. The billable codes are derived from the CMS list. The 6 | #' most recent version is used by default. 7 | -------------------------------------------------------------------------------- /benchmarks/icd-JSS3447-replication/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rocker/tidyverse:latest 2 | RUN mkdir /icd-JSS3447-repl/ 3 | WORKDIR /icd-JSS3447-repl/ 4 | COPY install-dependencies.R . 5 | RUN mkdir ~/.R 6 | RUN echo 'CFLAGS=-w' > ~/.R/Makevars 7 | RUN echo 'CXXFLAGS=-w' >> ~/.R/Makevars 8 | RUN echo 'CXX11FLAGS=-w' >> ~/.R/Makevars 9 | COPY bench-versus.R . 10 | COPY Makefile . 11 | COPY comorbidity_0.1.1.tar.gz . 12 | COPY medicalrisk_1.2.tar.gz . 13 | RUN make deps 14 | CMD make result7 15 | -------------------------------------------------------------------------------- /man-roxygen/billable.R: -------------------------------------------------------------------------------- 1 | #' @param leaf single logical value, whether to limit return codes also by 2 | #' whether they are billable, i.e. leaf nodes. This is really only designed 3 | #' for use with ICD-9-CM, ICD-10-CM etc, since the WHO versions are not 4 | #' designed for billing, but for public health and death reporting. 5 | #' @param billable single logical value, identical to 'leaf'. Leaf is preferred 6 | #' as most adaptations of WHO ICD codes are not oriented around money. 7 | -------------------------------------------------------------------------------- /man-roxygen/icd_name.R: -------------------------------------------------------------------------------- 1 | #' @param icd_name The name of the column in the \code{data.frame} which 2 | #' contains the ICD codes. This is a character vector of length one. If it is 3 | #' \code{NULL}, \code{icd9} will attempt to guess the column name, looking for 4 | #' progressively less likely possibilities until it matches a single column. 5 | #' Failing this, it will take the first column in the data frame. Specifying 6 | #' the column using this argument avoids the guesswork. 7 | -------------------------------------------------------------------------------- /man-roxygen/defined.R: -------------------------------------------------------------------------------- 1 | #' @param defined single logical value, if \code{TRUE}, will limit the search to 2 | #' those codes which appear in the official list, not just syntactically valid 3 | #' codes. Since nearly valid, out-dated or new codes may be missed, not 4 | #' limiting to officially defined values will be useful. Ultimately, there 5 | #' will need to be annual (and all-time) official lists of codes and the 6 | #' ability to test against a list for the year of the ICD-9 coding. 7 | -------------------------------------------------------------------------------- /man/attr_short_diag.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R 3 | \name{attr_short_diag} 4 | \alias{attr_short_diag} 5 | \title{Set short diagnosis flag in C++} 6 | \usage{ 7 | attr_short_diag(x, value = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{Any R object} 11 | 12 | \item{value}{\code{TRUE} or \code{FALSE}} 13 | } 14 | \description{ 15 | Set short diagnosis flag in C++ 16 | } 17 | \keyword{attribute} 18 | \keyword{internal} 19 | -------------------------------------------------------------------------------- /man-roxygen/mapping.R: -------------------------------------------------------------------------------- 1 | #' @param map named list containing vectors of ICD-9 codes. E.g. the AHRQ ICD-9 2 | #' comorbidities, contains \code{list(OBESE = c("2780", "27800", "27801", 3 | #' "27803", "V8554", "79391", "64910", "64911", "64912", "64913", "64914", 4 | #' "V8530", "V8531", "V8532", "V8533", "V8534", "V8535", "V8536", "V8537", 5 | #' "V8538", "V8539", "V8541", "V8542", "V8543", "V8544", "V8545" ), DEPRESS = 6 | #' c("3004", "30112", "3090", "3091", "311"))} amongst other longer groups. 7 | -------------------------------------------------------------------------------- /man/get_icd10cm2014_pc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2014_pc} 5 | \alias{get_icd10cm2014_pc} 6 | \title{ICD-10-CM Procedure codes for 2014} 7 | \description{ 8 | ICD-10-CM Procedure codes for 2014 9 | } 10 | \seealso{ 11 | \code{get_icd10cm2015_pc} \code{get_icd10cm2016_pc} 12 | \code{get_icd10cm2017_pc} \code{get_icd10cm2018_pc} 13 | \code{get_icd10cm2019_pc} 14 | } 15 | \keyword{datasets} 16 | -------------------------------------------------------------------------------- /man/get_icd10cm2015_pc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2015_pc} 5 | \alias{get_icd10cm2015_pc} 6 | \title{ICD-10-CM Procedure codes for 2015} 7 | \description{ 8 | ICD-10-CM Procedure codes for 2015 9 | } 10 | \seealso{ 11 | \code{get_icd10cm2014_pc} \code{get_icd10cm2016_pc} 12 | \code{get_icd10cm2017_pc} \code{get_icd10cm2018_pc} 13 | \code{get_icd10cm2019_pc} 14 | } 15 | \keyword{datasets} 16 | -------------------------------------------------------------------------------- /man/get_icd10cm2016_pc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2016_pc} 5 | \alias{get_icd10cm2016_pc} 6 | \title{ICD-10-CM Procedure codes for 2016} 7 | \description{ 8 | ICD-10-CM Procedure codes for 2016 9 | } 10 | \seealso{ 11 | \code{get_icd10cm2014_pc} \code{get_icd10cm2015_pc} 12 | \code{get_icd10cm2017_pc} \code{get_icd10cm2018_pc} 13 | \code{get_icd10cm2019_pc} 14 | } 15 | \keyword{datasets} 16 | -------------------------------------------------------------------------------- /man/get_icd10cm2017_pc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2017_pc} 5 | \alias{get_icd10cm2017_pc} 6 | \title{ICD-10-CM Procedure codes for 2017} 7 | \description{ 8 | ICD-10-CM Procedure codes for 2017 9 | } 10 | \seealso{ 11 | \code{get_icd10cm2014_pc} \code{get_icd10cm2015_pc} 12 | \code{get_icd10cm2016_pc} \code{get_icd10cm2018_pc} 13 | \code{get_icd10cm2019_pc} 14 | } 15 | \keyword{datasets} 16 | -------------------------------------------------------------------------------- /man/get_icd10cm2018_pc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2018_pc} 5 | \alias{get_icd10cm2018_pc} 6 | \title{ICD-10-CM Procedure codes for 2018} 7 | \description{ 8 | ICD-10-CM Procedure codes for 2018 9 | } 10 | \seealso{ 11 | \code{get_icd10cm2014_pc} \code{get_icd10cm2015_pc} 12 | \code{get_icd10cm2016_pc} \code{get_icd10cm2017_pc} 13 | \code{get_icd10cm2019_pc} 14 | } 15 | \keyword{datasets} 16 | -------------------------------------------------------------------------------- /man-roxygen/mapping-icd9.R: -------------------------------------------------------------------------------- 1 | #' @param icd9Mapping named list containing vectors of ICD-9 codes. E.g. the 2 | #' AHRQ comorbidities, contains \code{list(OBESE = c("2780", "27800", "27801", 3 | #' "27803", "V8554", "79391", "64910", "64911", "64912", "64913", "64914", 4 | #' "V8530", "V8531", "V8532", "V8533", "V8534", "V8535", "V8536", "V8537", 5 | #' "V8538", "V8539", "V8541", "V8542", "V8543", "V8544", "V8545" ), DEPRESS = 6 | #' c("3004", "30112", "3090", "3091", "311"))} amongst other longer groups. 7 | -------------------------------------------------------------------------------- /tests/testthat/test-examples.R: -------------------------------------------------------------------------------- 1 | context("function examples") 2 | 3 | # this is essentially duplicated by R CMD check, which runs the examples, but 4 | # doing this here allows test coverage to include more code, and perhaps to make 5 | # sure there are no warnings thrown. 6 | 7 | old_opts <- options(warn = 2) 8 | on.exit(options(old_opts), add = TRUE) 9 | 10 | # avoid skip spam in tests for older testthat 11 | skip_if_not_installed("testthat", minimum_version = "2.1") 12 | testthat::test_examples() 13 | -------------------------------------------------------------------------------- /tools/mk/strip.mk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env make 2 | #Enable using configure --enable-icd-strip 3 | #With binary stripping, size is about 10% on Linux, 90% on Mac. CRAN Windows DLL is already small. 4 | strippedLib: $(SHLIB) 5 | command -v strip >/dev/null && \ 6 | command -v uname >/dev/null && \ 7 | [ x$(uname -s) = xLinux ] && strip -S $(SHLIB) || true 8 | command -v strip >/dev/null && \ 9 | command -v uname >/dev/null && \ 10 | [ x$(uname -s) = xDarwin ] && strip -S $(SHLIB) || true 11 | .phony: strippedLib 12 | -------------------------------------------------------------------------------- /man/explain_table_worker.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/explain-table.R 3 | \name{explain_table_worker} 4 | \alias{explain_table_worker} 5 | \title{generate table of ICD code explanations} 6 | \usage{ 7 | explain_table_worker(x, hierarchy, short_code, condense, brief, warn, ...) 8 | } 9 | \description{ 10 | common code for generating full table of explanations of ICD codes 11 | } 12 | \author{ 13 | Ed Lee created, Jack Wasey updated 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /man/uranium_pathology.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{uranium_pathology} 5 | \alias{uranium_pathology} 6 | \title{United States Transuranium & Uranium Registries} 7 | \source{ 8 | \url{https://ustur.wsu.edu/about-us/} 9 | } 10 | \description{ 11 | This is an ICD-10 data set (not ICD-10-CM) with mortality from the United 12 | States Transuranium & Uranium Registries, published in the public domain. 13 | } 14 | \keyword{datasets} 15 | -------------------------------------------------------------------------------- /R/as_char_no_warn.R: -------------------------------------------------------------------------------- 1 | #' convert to character vector without warning 2 | #' @param x vector, typically numeric or a factor 3 | #' @return character vector 4 | #' @keywords internal 5 | #' @noRd 6 | as_char_no_warn <- function(x) { 7 | if (is.character(x)) { 8 | return(x) 9 | } 10 | old <- options(warn = -1) 11 | on.exit(options(old), add = TRUE) 12 | if (is.integer(x)) { 13 | return(fastIntToStringRcpp(x)) 14 | } 15 | if (is.factor(x)) { 16 | return(levels(x)[x]) 17 | } 18 | as.character(x) 19 | } 20 | -------------------------------------------------------------------------------- /tools/DESCRIPTION-minimalize.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ! [[ -f DESCRIPTION ]] && 4 | [[ -d icd ]] && 5 | { 6 | cd icd || 7 | { 8 | echo "DESCRIPTION not in current directory, and no icd DIRECTORY either" >&2; 9 | exit 1; 10 | }; 11 | } 12 | awk 'BEGIN {g=0} /^[A-Za-z]+:/ {f=0} /^Suggests:/ {f=1} { if (f) { if (!g){print "Suggests:\n testthat";g=1;}} else print $0; }' DESCRIPTION | 13 | awk '/^[A-Za-z]+:/ {f=0} /^VignetteBuilder:/ {f=1} !f' 14 | -------------------------------------------------------------------------------- /vignettes/efficiency.Rnw: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{pdfpages} 3 | \usepackage{pdflscape} 4 | %\VignetteIndexEntry{icd: Efficient Computation of Comorbidities from ICD Codes Using Sparse Matrix Multiplication in R} 5 | %\VignetteEncoding{UTF-8} 6 | %\VignetteKeyword{comorbidity, comorbidities, biomedical informatics, administrative data, matrix algebra, ICD-9, ICD-10, ICD-9-CM, ICD-10-CM, mapping, algorithm} 7 | \begin{document} 8 | \includepdf[pages=-, fitpaper=true]{efficiency-prebuilt.pdf} 9 | \end{document} 10 | 11 | -------------------------------------------------------------------------------- /R/assign.R: -------------------------------------------------------------------------------- 1 | #' Assign all the data in the package to the calling environment 2 | #' 3 | #' Used by \pkg{icd} to load all the data into its environment. This should not 4 | #' be needed by users. 5 | #' @examples 6 | #' \dontrun{ 7 | #' icd:::assign_icd_data() 8 | #' ls() 9 | #' } 10 | #' @keywords internal 11 | #' @noRd 12 | assign_icd_data <- function(env = parent.frame()) { 13 | data_names <- .ls_icd_data() 14 | lapply( 15 | data_names, 16 | function(x) { 17 | assign(x, get(x), envir = env) 18 | } 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /R/generate.R: -------------------------------------------------------------------------------- 1 | #' Generate random ICD-9 codes 2 | #' 3 | #' Uses leaf/billable ICD-10-CM codes from most recent edition 4 | #' @param n number to select, passed to \code{sample} 5 | #' @template short_code 6 | #' @keywords internal debugging datagen 7 | #' @noRd 8 | generate_random_short_icd10cm_bill <- function(n = 10, short_code = TRUE) { 9 | i <- icd10cm2019 10 | x <- sample( 11 | unlist( 12 | i[i$billable == 1, "code"] 13 | ), 14 | replace = TRUE, size = n 15 | ) 16 | if (short_code) x else short_to_decimal(x) 17 | } 18 | -------------------------------------------------------------------------------- /benchmarks/bench-strings.R: -------------------------------------------------------------------------------- 1 | requireNamespace("microbenchmark") 2 | requireNamespace("stringr") 3 | 4 | s <- icd:::random_string(1e4) 5 | microbenchmark::microbenchmark(icd:::trim(s), trimws(s)) 6 | 7 | x <- icd:::random_string(5e4) 8 | microbenchmark::microbenchmark( 9 | gsub(x = x, pattern = "A", replacement = "", fixed = TRUE, useBytes = TRUE), 10 | gsub(x = x, pattern = "A", replacement = "", fixed = TRUE, useBytes = TRUE, perl = TRUE), 11 | gsub(x = x, pattern = "A", replacement = ""), 12 | stringr::str_replace_all(x, "A", "") 13 | ) 14 | -------------------------------------------------------------------------------- /benchmarks/bench-appendMinor.R: -------------------------------------------------------------------------------- 1 | n <- 5e6 2 | mjrs <- as.character(sample(1:999, n, replace = TRUE)) 3 | mnrs <- as.character(sample(0:99, n, replace = TRUE)) 4 | microbenchmark::microbenchmark( 5 | icd9MajMinToCode(mjrs, mnrs, TRUE), 6 | icd9MajMinToCodeStd(mjrs, mnrs, TRUE), 7 | # icd9MajMinToCodePrePadded(mjrs, mnrs, TRUE), # removed from repo 8 | times = 10 9 | ) 10 | 11 | # std method about the same with O3 (4% faster, but no NA handling), but 50% quicker with O0 12 | # std method without doing padding is 5 times quicker than previous... 13 | -------------------------------------------------------------------------------- /man/shortcode_icd9.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/explain-table.R 3 | \name{shortcode_icd9} 4 | \alias{shortcode_icd9} 5 | \alias{shortcode_icd10} 6 | \title{set \code{short_to_decimal} attribute} 7 | \usage{ 8 | shortcode_icd9(x, short_code = guess_short(x)) 9 | 10 | shortcode_icd10(x, short_code = guess_short(x)) 11 | } 12 | \description{ 13 | Does not convert between decimal and short codes. Calling 14 | \code{short_to_decimal} should convert and set the attribute. 15 | } 16 | \keyword{internal} 17 | -------------------------------------------------------------------------------- /benchmarks/bench-dropLeadingZeroes.R: -------------------------------------------------------------------------------- 1 | library(microbenchmark) 2 | library(icd) 3 | x <- icd:::generate_random_decimal_icd9(1e6) 4 | microbenchmark( 5 | stringr::str_replace( 6 | icd:::as_char_no_warn(x), 7 | "[[:space:]]*([EeVv]?)(0*)([\\.[:digit:]]*)[[:space:]]*", 8 | "\\1\\3" 9 | ), 10 | stringr::str_replace( 11 | icd:::as_char_no_warn(x), 12 | "[[:space:]]*([EeVv]?)(0*)([\\.[:digit:]]*)[[:space:]]*", 13 | "\\1\\3" 14 | ), 15 | gsub("[[:space:]]*([EeVv]?)(0*)([\\.[:digit:]]*)[[:space:]]*", "\\1\\3", x), 16 | times = 1000 17 | ) 18 | -------------------------------------------------------------------------------- /src/cutil.c: -------------------------------------------------------------------------------- 1 | #include "cutil.h" 2 | #include 3 | #include 4 | #include 5 | 6 | SEXP getRListOrDfElement(SEXP list_or_df, const char *element_name) { 7 | SEXP names = PROTECT(Rf_getAttrib(list_or_df, R_NamesSymbol)); 8 | SEXP element = PROTECT(R_NilValue); 9 | int i; 10 | int len = Rf_length(list_or_df); 11 | for (i = 0; i < len; i++) { 12 | if (strcmp(CHAR(STRING_ELT(names, i)), element_name) == 0) { 13 | element = VECTOR_ELT(list_or_df, i); 14 | break; 15 | } 16 | } 17 | UNPROTECT(2); 18 | return element; 19 | } 20 | -------------------------------------------------------------------------------- /benchmarks/bench-addleadingzeroes.R: -------------------------------------------------------------------------------- 1 | if (require(microbenchmark)) { 2 | stopifnot(identical( 3 | icd:::icd9_add_leading_zeroes_alt_rcpp(c("1", "E2", "V1", "E"), short_code = TRUE), 4 | icd:::icd9_add_leading_zeroes_rcpp(c("1", "E2", "V1", "E"), short_code = TRUE) 5 | )) 6 | 7 | bad_codes <- sample(c("E2", "V01", "1234", "12", "1", "E99", "E987", "V"), 8 | size = 1e4, replace = TRUE 9 | ) 10 | microbenchmark::microbenchmark( 11 | icd:::icd9_add_leading_zeroes_alt_rcpp(bad_codes, short_code = TRUE), 12 | icd:::icd9_add_leading_zeroes_rcpp(bad_codes, short_code = TRUE) 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/categorize.cpp: -------------------------------------------------------------------------------- 1 | #include "local.hpp" 2 | #include "util.hpp" 3 | #include // for copy, sort, transform 4 | #include // for back_insert_iterator 5 | #include // for floor 6 | #include // for size_t, operator<< 7 | #include 8 | #include 9 | #include // for strcmp 10 | #include 11 | #include 12 | 13 | using namespace Rcpp; 14 | 15 | // # nocov start 16 | 17 | // [[Rcpp::export]] 18 | List categorize_rcpp() { 19 | Rcerr << "Not implemented in pure C++ yet"; 20 | return List::create(); 21 | } 22 | 23 | // # nocov end 24 | -------------------------------------------------------------------------------- /man-roxygen/deprecated-icd3.R: -------------------------------------------------------------------------------- 1 | #' @section Deprecated function names: Future versions of \pkg{icd} will drop 2 | #' the \code{icd_} prefix. For example, \code{charlson} should be used in 3 | #' favor of \code{icd_charlson}. To distinguish \pkg{icd} function calls, 4 | #' consider using the prefix \code{icd::} instead, e.g., \code{icd::charlson}. 5 | #' Functions which specifically operate on either ICD-9 or ICD-10 codes or 6 | #' their sub-types will retain the prefix. E.g. 7 | #' \code{\link{icd9_comorbid_ahrq}}. \pkg{icd} specific classes also retain 8 | #' the prefix, e.g., \code{\link{icd_wide_data}}. 9 | 10 | -------------------------------------------------------------------------------- /man/is.icd_long_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class.R 3 | \name{is.icd_long_data} 4 | \alias{is.icd_long_data} 5 | \alias{is.icd_wide_data} 6 | \title{Test for class describing patient data} 7 | \usage{ 8 | is.icd_long_data(x) 9 | 10 | is.icd_wide_data(x) 11 | } 12 | \arguments{ 13 | \item{x}{Typically a \code{data.frame}} 14 | } 15 | \description{ 16 | This function does not examine the data itself; it just checks whether one of 17 | the classes \code{icd_long_data} or \code{icd_wide_data} class is set. 18 | } 19 | \seealso{ 20 | \code{\link{icd_long_data}} 21 | } 22 | -------------------------------------------------------------------------------- /tests/testthat/test-build-maps-icd9-kids-elix.R: -------------------------------------------------------------------------------- 1 | context("ICD-9 map children all present") 2 | 3 | skip_slow("Skipping slow checking of ICD-9 comorbidity map children (elix)") 4 | 5 | test_that("AHRQ children same as saved", { 6 | for (i in icd9_map_ahrq) { 7 | expect_equal( 8 | children.icd9(i, defined = FALSE, short_code = TRUE), 9 | sort.icd9(i) 10 | ) 11 | } 12 | }) 13 | 14 | test_that("Elixhauser children same as saved", { 15 | for (i in icd9_map_quan_elix) { 16 | expect_equal( 17 | children.icd9(i, defined = FALSE, short_code = TRUE), 18 | sort.icd9(i) 19 | ) 20 | } 21 | }) 22 | -------------------------------------------------------------------------------- /tools/mk/travis-macos.mk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env make 2 | 3 | icd_osx_comp_ver = -9 4 | icd_osx_cxx = /usr/local/bin/g++ 5 | icd_osx_cc = /usr/local/bin/gcc 6 | icd_osx_fc_ver = $(shell sh -c "command -v gfortran || command -v gfortran$(icd_osx_comp_ver) || echo 'cannot find gfortran!' >&2" ) 7 | 8 | # try some prophylactic debugging: 9 | #@echo Old CC, etc are $(CXX) $(CXX11) $(CXX14) $(CXX17) $(CXX20) $(CC) $(FC) $(F77) 10 | 11 | CXX = $(icd_osx_cxx)$(icd_osx_comp_ver) 12 | CXX11 = $(CXX) 13 | CXX14 = $(CXX) 14 | CXX17 = $(CXX) 15 | CXX20 = $(CXX) 16 | CC = $(icd_osx_cc)$(icd_osx_comp_ver) 17 | FC = $(icd_osx_fc_ver) 18 | F77 = $(FC) 19 | -------------------------------------------------------------------------------- /tools/mk/travis-nowarn.mk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env make 2 | 3 | # this is mainly for the enormously verbose RcppEigen warnings, which come with any compilation which does LinkingTo RcppEigen, not the package installation itself. 4 | icd_shutup_flags = -Wno-unknown-warning-option -Wno-unused-parameter -Wno-unused-variable -Wno-ignored-attributes -Wno-cast-function-type -Wno-unknown-pragmas 5 | CXXFLAGS += $(icd_shutup_flags) 6 | CXX11FLAGS += $(icd_shutup_flags) 7 | CXX14FLAGS += $(icd_shutup_flags) 8 | CXX17FLAGS += $(icd_shutup_flags) 9 | CXX20FLAGS += $(icd_shutup_flags) 10 | CFLAGS += $(icd_shutup_flags) 11 | FCFLAGS += $(icd_shutup_flags) 12 | -------------------------------------------------------------------------------- /benchmarks/bench-comorbid-icd9-1e7-plain.R: -------------------------------------------------------------------------------- 1 | # generate a bunch of random patients and get comorbidities, intended for 2 | # stressing, e.g., with valgrind 3 | library(icd) 4 | library(microbenchmark) 5 | library(magrittr) 6 | library(R.cache) 7 | library(profvis) 8 | ten_million_random_pts <- R.cache::loadCache(key = list("ten_million_random_pts"), suffix = "icd.Rcache") 9 | if (is.null(ten_million_random_pts)) { 10 | ten_million_random_pts <- icd:::generate_random_pts(1e7) 11 | R.cache::saveCache(ten_million_random_pts, key = list("ten_million_random_pts"), suffix = "icd.Rcache") 12 | } 13 | comorbid_ahrq(ten_million_random_pts, preclean = FALSE) 14 | -------------------------------------------------------------------------------- /man/as.comorbidity_map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class.R 3 | \name{as.comorbidity_map} 4 | \alias{as.comorbidity_map} 5 | \title{Set the class of a named list to show it is a comorbidity map.} 6 | \usage{ 7 | as.comorbidity_map(x) 8 | } 9 | \arguments{ 10 | \item{x}{A list of depth one, with unique names, and elements that are 11 | character vectors.} 12 | } 13 | \description{ 14 | Set the class of a named list to show it is a comorbidity map. 15 | } 16 | \seealso{ 17 | Other ICD data types: 18 | \code{\link{set_icd_class}}, 19 | \code{\link{wide_vs_long}} 20 | } 21 | \concept{ICD data types} 22 | -------------------------------------------------------------------------------- /tools/compare datasets.R: -------------------------------------------------------------------------------- 1 | # compare data-sets when data built on different platforms: 2 | library(icd) 3 | library(crayon) 4 | if (!exists("e", mode = "environment") || 5 | length(ls(envir = e)) == 0) { 6 | d2_dir <- "/tmp/d3" 7 | e <- new.env() 8 | nms <- lapply(list.files(d2_dir, full.names = TRUE), load, envir = e) 9 | nms <- unlist(nms) 10 | } 11 | for (n in nms) { 12 | message(blue("Working on "), yellow(n)) 13 | xo <- get(x = n, envir = as.environment("package:icd")) 14 | xe <- get(x = n, envir = e) 15 | if (identical(xo, xe)) { 16 | message(green("Identical")) 17 | next 18 | } 19 | print(testthat::compare(xo, xe)) 20 | } 21 | -------------------------------------------------------------------------------- /tools/find_icd10cm_permutations.r: -------------------------------------------------------------------------------- 1 | 2 | #now some development code to see what permutations there are of ICD-10 codes 3 | #based on the 2016 CM set. 4 | 5 | i10 <- icd10cm2019$code 6 | 7 | alpha_in_tail <- grep("[[:alpha:]]", i10tail, value = TRUE) 8 | alpha_in_tail_bool <- grepl("[[:alpha:]].*[[:alpha:]].*", x = i10) 9 | alpha_in_tail <- i10[alpha_in_tail_bool] 10 | unique(gsub("[[:digit:]]", replacement = "", x = alpha_in_tail)) 11 | 12 | # verify, e.g. J in middle? 13 | grep("[[:alpha::]].*J.*", i10) 14 | 15 | # find unique characters at each position from 4 to 7 16 | for (i in 1:7) { 17 | message(i) 18 | print(sort(unique(substring(alpha_in_tail, i, i)))) 19 | } 20 | -------------------------------------------------------------------------------- /icd.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Yes 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --with-keep.source --install-tests 21 | PackageBuildArgs: --compact-vignettes=gs+qpdf 22 | PackageBuildBinaryArgs: --preclean --example --install-tests --no-clean-on-error --with-keep.source --data-compress=none 23 | PackageRoxygenize: rd,namespace 24 | 25 | QuitChildProcessesOnExit: Yes 26 | -------------------------------------------------------------------------------- /benchmarks/bench-children.R: -------------------------------------------------------------------------------- 1 | if (requireNamespace("microbenchmark")) { 2 | microbenchmark::microbenchmark( 3 | icd:::icd9ChildrenShort(c("001", 100:500), onlyReal = TRUE), 4 | icd:::icd9ChildrenShort_alt11(c("001", 100:500), onlyReal = TRUE), 5 | times = 5 6 | ) 7 | # C++11 about 15% faster for this data 8 | } 9 | 10 | microbenchmark(icd9ChildrenShort("001", T), icd9ChildrenShortStd("001", T), times = 100) 11 | microbenchmark(icd9ChildrenShort(c("001", 100:400), T), 12 | icd9ChildrenShortUnordered(c("001", 100:400), T), 13 | icd9ChildrenShortStd(c("001", 100:400), T), 14 | times = 10 15 | ) 16 | # } 17 | #' # un-ordered set much faster, but may still need to sort result 18 | -------------------------------------------------------------------------------- /vignettes/country-lang-vers.Rnw: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{pdfpages} 3 | \usepackage{pdflscape} 4 | %\VignetteIndexEntry{Working with World Health Organization ICD codes and national editions, and different languages} 5 | %\VignetteEncoding{UTF-8} 6 | %\VignetteKeyword{World Health Organization, World Health Organisation, WHO, OMS, Organisation Mondiale de la Santé, ICD-9, ICD-10, ICD-11, France, Belgium, Belgique} 7 | \begin{document} 8 | % See: http://mirrors.ctan.org/macros/latex/contrib/pdfpages/pdfpages.pdf and http://mirrors.ibiblio.org/CTAN/macros/latex/contrib/pdflscape/pdflscape.pdf 9 | \includepdf[pages=-, fitpaper=true]{country-lang-vers-prebuilt.pdf} 10 | \end{document} 11 | -------------------------------------------------------------------------------- /tests/testthat/test-data-fun.R: -------------------------------------------------------------------------------- 1 | context("data fun") 2 | 3 | test_that("download and parse generated data functions", { 4 | skip_slow("checking all data fetch/download/get") 5 | ns <- asNamespace("icd") 6 | for (b in c( 7 | .data_names, 8 | "icd10cm_latest" 9 | )) { 10 | inf <- paste("Data fun name:", b) 11 | expect_true(.exists_in_ns(.get_fetcher_name(b)), info = inf) 12 | if (.offline() || !.exists_in_cache(b)) { 13 | skip(paste( 14 | "Regardless of interactivity, don't download during tests and", 15 | inf, "is not in the cache." 16 | )) 17 | } 18 | f <- .get_fetcher_fun(b) 19 | expect_is(f(), "data.frame", info = inf) 20 | } 21 | }) 22 | -------------------------------------------------------------------------------- /benchmarks/bench-parse-rtf-lookup-fourth.R: -------------------------------------------------------------------------------- 1 | # compare environement to standard %in% search for RTF parsing 2 | 3 | requireNamespace("microbenchmark") 4 | load("benchmarks/rtf-fourth-out.rda") 5 | load("benchmarks/lookup-fourth.rda") 6 | print(microbenchmark::microbenchmark(rtf_lookup_fourth(out = rtf_fourth_out, lookup_fourth = lookup_fourth, verbose = FALSE), 7 | rtf_lookup_fourth_alt_env(out = rtf_fourth_out, lookup_fourth = lookup_fourth, verbose = FALSE), 8 | times = 100L 9 | )) 10 | stopifnot(identical( 11 | rtf_lookup_fourth(out = rtf_fourth_out, lookup_fourth = lookup_fourth, verbose = FALSE), 12 | rtf_lookup_fourth_alt_env(out = rtf_fourth_out, lookup_fourth = lookup_fourth, verbose = FALSE) 13 | )) 14 | -------------------------------------------------------------------------------- /man/sub-sub-.comorbidity_map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class.R 3 | \name{[[.comorbidity_map} 4 | \alias{[[.comorbidity_map} 5 | \title{Extract vector of codes from an ICD comorbidity map} 6 | \usage{ 7 | \method{[[}{comorbidity_map}(x, index, ...) 8 | } 9 | \arguments{ 10 | \item{x}{comorbidity map, which is a named list} 11 | 12 | \item{index}{integer} 13 | 14 | \item{...}{arguments passed on to other functions} 15 | } 16 | \description{ 17 | Equivalent to a list, but preserves class of extracted vector. 18 | } 19 | \examples{ 20 | # show that attributes are preserved when subsetting 21 | stopifnot(is.short_diag(icd10_map_ahrq[[1]])) 22 | } 23 | \keyword{internal} 24 | -------------------------------------------------------------------------------- /tools/install-quick.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | IFS=$'\n\t' 4 | # shellcheck disable=SC1090 5 | source "${ICD_HOME:-$HOME/icd}/tools/build-quick.sh" 6 | 7 | ( 8 | [[ -f "$HOME/.R/Makevars.quick" ]] && export R_MAKEVARS_USER="$HOME/.R/Makevars.quick" 9 | MAKEFLAGS=-j$(getconf _NPROCESSORS_ONLN) 10 | export MAKEFLAGS 11 | R CMD INSTALL --debug \ 12 | --data-compress=none \ 13 | --configure-args="CXX11FLAGS=-O0" \ 14 | --install-tests \ 15 | --no-staged-install \ 16 | icd*.tar.gz 17 | 18 | # --library="$install_dir" \ 19 | # --no-byte-compile \ 20 | # --no-resave-data \ 21 | # --no-build-vignettes \ 22 | # --no-clean-on-error \ 23 | # --no-docs \ 24 | ) 25 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | data/* binary 4 | src/* text=lf 5 | R/* text=lf 6 | tools/* text=lf 7 | *.rtf diff=astextplain 8 | *.RTF diff=astextplain 9 | 10 | # WIP: 11 | # need to run: 12 | # git config --local include.path ../.gitconfig 13 | # for local PNG/PDF friendly diffing to work 14 | *.png diff=png 15 | *.pdf diff=pdf 16 | 17 | ## after my bug report, I think Rcpp is now more deterministic 18 | ## git config diff.nodiff.command /usr/bin/true or /bin/true 19 | # *RcppExports* diff=nodiff 20 | # *.Rd diff=nodiff 21 | ## git config then has 'merge.theirs.driver true' 22 | # *RcppExports* merge=theirs 23 | # *.Rd merge=theirs 24 | 25 | /NEWS.md merge=union 26 | -------------------------------------------------------------------------------- /man/attr_decimal_diag.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R 3 | \name{attr_decimal_diag} 4 | \alias{attr_decimal_diag} 5 | \title{Set ICD short-form diagnosis code attribute} 6 | \usage{ 7 | attr_decimal_diag(x, value = TRUE) 8 | } 9 | \description{ 10 | Doing this in an R function doesn't work for 'void' equivalent, and does a 11 | copy if the updated object is returned. 12 | } 13 | \examples{ 14 | j <- "100" 15 | attr(j, "icd_short_diag") <- TRUE 16 | j 17 | attr(j, "icd_short_diag") <- FALSE 18 | j 19 | icd:::attr_decimal_diag(j) 20 | as.decimal_diag(j) 21 | # if pryr is installed, use address and refs to see what is going on 22 | } 23 | \keyword{attribute} 24 | \keyword{internal} 25 | -------------------------------------------------------------------------------- /man/get_icd10cm_latest.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R, R/icd-cm-ver.R 3 | \docType{data} 4 | \name{get_icd10cm_latest} 5 | \alias{get_icd10cm_latest} 6 | \title{The latest available version of ICD-10-CM in this package} 7 | \usage{ 8 | get_icd10cm_latest() 9 | 10 | get_icd10cm_latest() 11 | } 12 | \description{ 13 | The latest available version of ICD-10-CM in this package 14 | 15 | The latest available ICD-10-CM data in this package 16 | } 17 | \details{ 18 | This is an active binding, so is exported explicitly 19 | 20 | This is an active binding, so is exported explicitly 21 | } 22 | \examples{ 23 | a <- get_icd10cm_latest() 24 | identical(a, icd10cm2019) 25 | } 26 | \keyword{datasets} 27 | -------------------------------------------------------------------------------- /.aspell/defaults.R: -------------------------------------------------------------------------------- 1 | vignettes <- list(control = c("--master=en_US", "--add-extra-dicts=en_GB"), 2 | personal = "words.pws", 3 | dictionaries = c("en_stats", "icdwords")) 4 | Rd_files <- list(control = c("--master=en_US", "--add-extra-dicts=en_GB"), 5 | personal = "words.pws", 6 | dictionaries = c("en_stats", "icdwords")) 7 | R_files <- list(control = c("--master=en_US", "--add-extra-dicts=en_GB"), 8 | personal = "words.pws", 9 | dictionaries = c("en_stats", "icdwords")) 10 | C_files <- list(control = c("--master=en_US", "--add-extra-dicts=en_GB"), 11 | personal = "words.pws", 12 | dictionaries = c("en_stats", "icdwords")) 13 | 14 | -------------------------------------------------------------------------------- /man/icd10_comorbid_reduce.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/comorbid.R 3 | \name{icd10_comorbid_reduce} 4 | \alias{icd10_comorbid_reduce} 5 | \title{ICD-10 comorbidities by reducing problem size} 6 | \usage{ 7 | icd10_comorbid_reduce( 8 | x = x, 9 | map, 10 | visit_name, 11 | icd_name, 12 | short_code, 13 | short_map, 14 | return_df, 15 | return_binary = FALSE, 16 | categorize_fun = categorize_simple, 17 | ... 18 | ) 19 | } 20 | \description{ 21 | Use method to reduce ICD-10 problem by initially finding only relevant codes 22 | in the map, then populating map only with the exact patient ICD codes (not 23 | the original map codes), before doing categorization. 24 | } 25 | \keyword{internal} 26 | -------------------------------------------------------------------------------- /src/convert.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CONVERT_H_ 2 | #define CONVERT_H_ 3 | 4 | #include "icd_types.hpp" 5 | using namespace Rcpp; 6 | 7 | // need default argument here for other functions to exploit, 8 | // but this is then not exported by Rcpp (which works on the function body). 9 | CV icd9PartsToShort(const List &parts); 10 | CV icd9PartsToDecimal(const List &parts); 11 | List majMinToParts(const CV &mjr, const CV &mnr); 12 | List icd9ShortToParts(const CV &icd9Short, const String& mnr_empty = ""); 13 | List icd9DecimalToParts(const CV &icd9Decimal, const String& mnr_empty = ""); 14 | CV icd9DecimalToShort(const CV &icd9Decimal); 15 | CV icd9ShortToDecimal(const CV &icd9Short); 16 | CV icd9GetMajor(const CV &icd9, const bool isShort); 17 | 18 | #endif /* CONVERT_H_ */ 19 | -------------------------------------------------------------------------------- /src/refactor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REFACTOR_H_ 2 | #define REFACTOR_H_ 3 | 4 | #include "local.hpp" 5 | 6 | using namespace Rcpp; 7 | IntegerVector factorNoSort(const CharacterVector &x, 8 | const CharacterVector &levels, 9 | const bool na_rm); 10 | Rcpp::IntegerVector refactor(const IntegerVector &x, 11 | const CV &new_levels, 12 | const bool exclude_na, 13 | const bool validate = false); 14 | Rcpp::IntegerVector refactor_narm(const IntegerVector &x, 15 | const CV &new_levels, 16 | const bool validate = false); 17 | bool factorIsValid(const IntegerVector &f); 18 | #endif /* REFACTOR_H_ */ 19 | -------------------------------------------------------------------------------- /src/.clang-format: -------------------------------------------------------------------------------- 1 | #BasedOnStyle: LLVM 2 | AlignAfterOpenBracket: Align 3 | AlignConsecutiveAssignments: true 4 | AlignEscapedNewlines: Left 5 | AlignOperands: true 6 | AlignTrailingComments: true 7 | AllowAllParametersOfDeclarationOnNextLine: true 8 | AllowShortBlocksOnASingleLine: true 9 | AllowShortFunctionsOnASingleLine: All 10 | AllowShortIfStatementsOnASingleLine: true 11 | AllowShortLoopsOnASingleLine: true 12 | AlwaysBreakBeforeMultilineStrings: false 13 | BinPackArguments: false 14 | BinPackParameters: false 15 | BreakBeforeBinaryOperators: None 16 | BreakBeforeBraces: Attach 17 | ColumnLimit: 80 18 | CommentPragmas: ^' 19 | ContinuationIndentWidth: 2 20 | IndentWidth: 2 21 | PenaltyBreakBeforeFirstCallParameter: 100000 22 | ReflowComments: true 23 | Standard: Cpp11 24 | TabWidth: 2 25 | UseTab: false 26 | 27 | -------------------------------------------------------------------------------- /tools/check-cran.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #shellcheck disable=SC2012 3 | set -eu 4 | IFS=$'\n\t' 5 | ICD_HOME="${ICD_HOME:-${HOME}/icd}" 6 | tmpd=$(mktemp -d /tmp/icdcheckcran.XXXXXXXXXXX) 7 | function finish { 8 | # rm -rf "$tmpd" 9 | echo "Finished with $tmpd" >&2 10 | } 11 | trap finish EXIT 12 | cd "$tmpd" 13 | # build with standard release options, including compacting vignettes 14 | "${ICD_HOME}"/tools/build-full.sh 15 | # for all environment variable options see here: 16 | # https://cran.r-project.org/doc/manuals/r-release/R-ints.html#Tools 17 | #R_MAKEVARS_USER="$HOME/.R/Makevars.clang" \ 18 | 19 | # using --as-cran, I think, over-rides any user environment for check 20 | tarball="$(ls -t "$tmpd"/icd*.tar.gz | head -1)" 21 | R_CHECK_ENVIRON="${ICD_HOME}/env/cran" \ 22 | R CMD check "${tarball}" 23 | -------------------------------------------------------------------------------- /tools/check-full.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #shellcheck disable=SC2012 3 | set -eu 4 | IFS=$'\n\t' 5 | ICD_HOME="${ICD_HOME:-${HOME}/icd}" 6 | tmpd=$(mktemp -d /tmp/icdcheckfull.XXXXXXXXXXX) 7 | function finish { 8 | # rm -rf "$tmpd" 9 | echo "Finished with $tmpd" >&2 10 | } 11 | trap finish EXIT 12 | cd "$tmpd" 13 | # build with standard release options, including compacting vignettes 14 | "${ICD_HOME}"/tools/build-full.sh 15 | # for all environment variable options see here: 16 | # https://cran.r-project.org/doc/manuals/r-release/R-ints.html#Tools 17 | # R_MAKEVARS_USER="$HOME/.R/Makevars.mac.quick" \ 18 | 19 | # using --as-cran, I think, over-rides any user environment for check 20 | tarball="$(ls -t "$tmpd"/icd*.tar.gz | head -1)" 21 | R_CHECK_ENVIRON="${ICD_HOME}/env/full" \ 22 | R CMD check "${tarball}" 23 | -------------------------------------------------------------------------------- /man-roxygen/visit_name.R: -------------------------------------------------------------------------------- 1 | #' @param visit_name The name of the column in the data frame which contains the 2 | #' patient or visit identifier. Typically this is the visit identifier, since 3 | #' patients come leave and enter hospital with different ICD-9 codes. It is a 4 | #' character vector of length one. If left empty, or \code{NULL}, then an 5 | #' attempt is made to guess which field has the ID for the patient encounter 6 | #' (not a patient ID, although this can of course be specified directly). The 7 | #' guesses proceed until a single match is made. Data frames may be wide with 8 | #' many matching fields, so to avoid false positives, anything but a single 9 | #' match is rejected. If there are no successful guesses, and \code{visit_id} 10 | #' was not specified, then the first column of the data frame is used. 11 | -------------------------------------------------------------------------------- /src/fastIntToString.cpp: -------------------------------------------------------------------------------- 1 | #include "icd_types.hpp" 2 | #include // for sprintf, size_t 3 | #include 4 | #include 5 | 6 | using namespace Rcpp; 7 | 8 | //' @title Convert integers to strings as quickly as possible 9 | //' @description Have tried R, \code{sprintf} with \CRANpkg{Rcpp} and C++ 10 | //' standard library. Doesn't do bounds checking, but limited by length of 11 | //' integers. 12 | //' @param x Vector of integers 13 | //' @return Vector of characters 14 | //' @keywords internal manip 15 | //' @noRd 16 | // [[Rcpp::export]] 17 | CharacterVector fastIntToStringRcpp(IntegerVector x) { 18 | size_t len = x.size(); 19 | CharacterVector out(len); 20 | char buffer[32]; 21 | for (size_t i = 0; i != len; ++i) { 22 | sprintf(buffer, "%u", x[i]); 23 | out[i] = buffer; 24 | } 25 | return out; 26 | } 27 | -------------------------------------------------------------------------------- /tools/configure-and-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eux 3 | 4 | echo "This is a dirty, not recommended way to build the library quickly, mainly just to test that configure script works." 5 | 6 | declare R_HOME 7 | [ "x${R_HOME-}" = x ] && R_HOME="$(R RHOME)" 8 | 9 | 10 | CXX_STD=CXX17 11 | 12 | PKG_CXXFLAGS="-w $(Rscript -e 'Rcpp:::CxxFlags()') $(Rscript -e 'RcppEigen:::CxxFlags()')" 13 | PKG_CFLAGS="-w" 14 | # CXX="ccache g++" 15 | # CC="ccache gcc" 16 | CXX=$("${R_HOME}/bin/R" CMD config CXX) 17 | CC=$("${R_HOME}/bin/R" CMD config CC) 18 | #MAKEFLAGS=-j8 19 | export PKG_CXXFLAGS PKG_CFLAGS CC CXX CXX_STD 20 | export PATH="/usr/bin/ccache:${PATH}" 21 | 22 | cd "${ICD_HOME?}" 23 | autoreconf 24 | ./configure --enable-icd-makevars --enable-icd-shutup --enable-icd-strip 25 | R CMD SHLIB --preclean --output=/tmp/icd.shlib src/*.cpp src/*.c 26 | -------------------------------------------------------------------------------- /tests/testthat/test-explain-icd10.R: -------------------------------------------------------------------------------- 1 | context("explain ICD-10-CM codes") 2 | # see also test-explain-who 3 | test_that("basic explain ICD-10 codes", { 4 | i10 <- list( 5 | "A00" = "Cholera", 6 | "Z998" = "Dependence on other enabling machines and devices" 7 | ) 8 | for (n in names(i10)) { 9 | expect_identical(x <- explain_code(n), i10[[n]]) 10 | expect_identical(explain_code(as.icd10(n)), x) 11 | expect_identical(explain_code(as.icd10cm(n)), x) 12 | } 13 | }) 14 | 15 | test_that("some majors seem to differ when generated on Mac vs Linux", { 16 | expect_identical( 17 | explain_code.icd10cm("K87", brief = TRUE), 18 | "Disord of GB, biliary trac and pancreas in dis classd elswhr" 19 | ) 20 | expect_identical( 21 | explain_code.icd10cm("I79", brief = TRUE), 22 | "Disord of art, arterioles and capilare in dis classd elswhr" 23 | ) 24 | }) 25 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | # this is common code to all the tests, each of which runs test_check with a 2 | # different filter: 3 | library("icd") 4 | library("testthat", warn.conflicts = FALSE, quietly = TRUE) 5 | icd:::.show_options() 6 | # Definitely don't download data on CRAN 7 | if (!icd:::.env_var_is_true("NOT_CRAN")) { 8 | old_offline <- options("icd.offline" = TRUE) 9 | on.exit(options(old_offline), add = TRUE) 10 | } else { 11 | old_offline <- options("icd.offline" = FALSE) 12 | on.exit(options(old_offline), add = TRUE) 13 | if (icd:::.env_var_is_true("ICD_TEST_SLOW")) { 14 | old_test_slow <- options("icd.test_slow" = TRUE) 15 | on.exit(options(old_test_slow), add = TRUE) 16 | } 17 | } 18 | old_interact <- options("icd.interact" = FALSE) 19 | on.exit(options(old_interact), add = TRUE) 20 | icd:::.show_options() 21 | testthat::test_check("icd") 22 | icd:::.show_options() 23 | -------------------------------------------------------------------------------- /benchmarks/icd-JSS3447-replication/find_comobidity_cutoff.R: -------------------------------------------------------------------------------- 1 | # The comorbidity package optionally uses a parallel flag. Here we benchmark 2 | # comorbidity against itself with and without parallel so we can choose the best 3 | # option to compare to 'icd'. Unfortunately, both are slow, so this may take 4 | # many minutes or hours, depending on hardware. 5 | 6 | # The 'install-dependencies.R' and 'bench-versus.R" scripts should be run first. 7 | 8 | n <- 10^(0L:5L) 9 | cmb_res <- bench::press(n = n, { 10 | pts <- get_pts(n, dz_per_pt = 20) 11 | bench::mark( 12 | comorbidity::comorbidity( 13 | x = pts, id = "visit_id", code = "code", score = "charlson_icd9", 14 | parallel = TRUE 15 | ), 16 | comorbidity::comorbidity( 17 | x = pts, id = "visit_id", code = "code", score = "charlson_icd9", 18 | parallel = FALSE 19 | ) 20 | ) 21 | }) 22 | print(cmb_res) 23 | -------------------------------------------------------------------------------- /man/expand_range.icd10cm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ranges.R 3 | \name{expand_range.icd10cm} 4 | \alias{expand_range.icd10cm} 5 | \title{Expand range of ICD-10 codes returning only defined codes in ICD-10-CM} 6 | \usage{ 7 | \method{expand_range}{icd10cm}(start, end, short_code = guess_short(c(start, end)), defined, ...) 8 | } 9 | \arguments{ 10 | \item{start}{character vector of length one containing an ICD code} 11 | 12 | \item{end}{character vector of length one containing an ICD code} 13 | } 14 | \description{ 15 | This will need generalizing to any list of officially defined codes, e.g. WHO 16 | or other. There are so many permutations of alphanumeric characters after the 17 | decimal place that it would be easy to generate many millions with simple 18 | ranges, the vast majority of which would be undefined. 19 | } 20 | \keyword{internal} 21 | -------------------------------------------------------------------------------- /man-roxygen/widevlong.R: -------------------------------------------------------------------------------- 1 | #' Note the distinction between labelling existing data with any classes which 2 | #' \code{icd} provides, and actually converting the structure of the data. 3 | #' @section Long and Wide Formats: As is common with many data sets, key 4 | #' variables can be concentrated in one column or spread over several. Tools 5 | #' format of clinical and administrative hospital data, we can perform the 6 | #' conversion efficiently and accurately, while keeping some metadata about 7 | #' the codes intact, e.g. whether they are ICD-9 or ICD-10. 8 | #' @section Data structure: Long or wide format ICD data are all expected to be 9 | #' in a data frame. The \code{data.frame} itself does not carry any ICD 10 | #' classes at the top level, even if it only contains one type of code; 11 | #' whereas its constituent columns may have a class specified, e.g. 12 | #' \code{icd9} or \code{icd10who}. 13 | -------------------------------------------------------------------------------- /man/set_icd10cm_active_year.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/icd-cm-ver.R 3 | \name{set_icd10cm_active_year} 4 | \alias{set_icd10cm_active_year} 5 | \alias{get_icd10cm_active_year} 6 | \title{Get or set the annual version of ICD-10-CM to use} 7 | \usage{ 8 | set_icd10cm_active_year(ver, check_exists = TRUE) 9 | 10 | get_icd10cm_active_year() 11 | } 12 | \arguments{ 13 | \item{ver}{Character vector of length one: the version of ICD-10-CM to use, 14 | corresponding to the suffix of the \code{data.frame} name, e.g., for 2019 15 | ICD-10-CM, use \code{"icd10cm2019"} for Dutch 2014 ICD-CM translations, use 16 | \code{"icd10cm2014_nl"}} 17 | 18 | \item{check_exists}{\code{TRUE} by default, which forces a check that the 19 | requested version is actually available in this R session.} 20 | } 21 | \description{ 22 | Get or set the annual version of ICD-10-CM to use 23 | } 24 | -------------------------------------------------------------------------------- /tools/bibfix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #all=all.bib 4 | 5 | command -v bibtool >/dev/null 2>&1 || { echo >&2 "I require bibtool but it's not installed. Aborting."; exit 1; } 6 | 7 | if [ -d vignettes ]; then 8 | pushd vignettes || { echo "cannot change to vignette directory"; exit 1; } 9 | trap popd EXIT 10 | fi 11 | 12 | # make sure there are no unescaped underscores in the URLs: 13 | for bib in icdjss.bib icdpkg.bib gplv3.bib other.bib 14 | do 15 | if grep '[^\]_' "$bib" | grep -v ^@ 16 | then 17 | echo "Underscores found in $bib entries. Fixing now." 18 | for n in {0..12} 19 | do 20 | [[ -v VERBOSE ]] && "echo ${n}" 21 | echo -n "." 22 | perl -pi -e 's/(url.*[^\\])_(.*)/\1\\_\2/g' "$bib" 23 | done 24 | else 25 | echo -e "\nNo underscores found in $bib" >&2 26 | fi 27 | done 28 | 29 | #bibtool -s gplv3.bib other.bib icdjss.bib -- preserve.key.case=on > "$all" 30 | exit 0 31 | -------------------------------------------------------------------------------- /man/with_icd10cm_version.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/icd-cm-ver.R 3 | \name{with_icd10cm_version} 4 | \alias{with_icd10cm_version} 5 | \title{Evaluate code with a particular version of ICD-10-CM} 6 | \usage{ 7 | with_icd10cm_version(ver, code) 8 | } 9 | \arguments{ 10 | \item{ver}{Character vector of length one: the version of ICD-10-CM to use, 11 | corresponding to the suffix of the \code{data.frame} name, e.g., for 2019 12 | ICD-10-CM, use \code{"icd10cm2019"} for Dutch 2014 ICD-CM translations, use 13 | \code{"icd10cm2014_nl"}} 14 | 15 | \item{code}{Code block to execute, may be in braces, or a single statement 16 | without braces.} 17 | } 18 | \description{ 19 | Temporarily sets and restores the option \code{icd.icd10cm_active_year}, 20 | analogous to functions in \CRANpkg{withr}. 21 | } 22 | \examples{ 23 | icd:::.show_options() 24 | with_icd10cm_version("2014", icd:::.show_options()) 25 | } 26 | -------------------------------------------------------------------------------- /tools/check-plus.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #shellcheck disable=SC2012 3 | set -eu 4 | IFS=$'\n\t' 5 | ICD_HOME="${ICD_HOME:-${HOME}/icd}" 6 | tmpd=$(mktemp -d /tmp/icdcheckplus.XXXXXXXXXXX) 7 | function finish { 8 | # rm -rf "$tmpd" 9 | echo "Finished with $tmpd" >&2 10 | } 11 | trap finish EXIT 12 | cd "$tmpd" 13 | # build with standard release options, including compacting vignettes 14 | "${ICD_HOME}"/tools/build-full.sh 15 | # for all environment variable options see here: 16 | # https://cran.r-project.org/doc/manuals/r-release/R-ints.html#Tools 17 | #R_MAKEVARS_USER="$HOME/.R/Makevars.clang" \ 18 | #R_CHECK_CONSTANTS=5 \ 19 | # N.b. R_CHECK_CONSTANTS and R_JIT_STRATEGY work together, but can make examples and tests run very slowly. 20 | # using --as-cran, I think, over-rides any user environment for check 21 | tarball="$(ls -t "$tmpd"/icd*.tar.gz | head -1)" 22 | R_CHECK_ENVIRON="${ICD_HOME}/env/plus" \ 23 | R CMD check "${tarball}" 24 | -------------------------------------------------------------------------------- /tools/find-icd-home.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # find icd source/development directory, warn if not where expected 4 | 5 | # this should be sourced, not executed 6 | 7 | find_icd_home() { 8 | [[ -n ${ICD_HOME:-} ]] && echo "$ICD_HOME" && return 0 9 | declare -a try_dirs 10 | try_dirs=( 11 | "${HOME}/icd" 12 | "${HOME}/rprojects/icd" 13 | "${HOME}/work/icd" 14 | ) 15 | for d in "${try_dirs[@]}"; do 16 | [[ -e "$d" ]] && 17 | [[ -d "$d" ]] && 18 | [[ -f "${d}/DESCRIPTION" ]] && 19 | echo "${d}" && 20 | return 0 21 | 22 | continue 23 | done 24 | echo "Unable to find icd development directory in usual places. Finding first from $HOME" >&2 25 | find "$HOME" -maxdepth 3 -name "icd" -type d | head -1 26 | } 27 | 28 | (return 0 2>/dev/null) || { 29 | echo "This script should be sourced. Then call bash function 'find_icd_home'" >&2; exit 1; } 30 | -------------------------------------------------------------------------------- /man/get_icd10cm2019_pc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10cm2019_pc} 5 | \alias{get_icd10cm2019_pc} 6 | \title{ICD-10-CM Procedure Codes} 7 | \format{ 8 | A named list of data frames. The elements of the list are named by 9 | the year, e.g., \code{"2018"}. Each data frame contains two character 10 | columns, the first, named \code{code} is the procedure code; the second, 11 | named \code{desc}, has the description. 12 | } 13 | \description{ 14 | ICD-10-PCS is the annually-updated set of procedure codes designed by 3M for 15 | the US CMS. There is no directory of WHO ICD procedure codes. 16 | } 17 | \seealso{ 18 | \code{get_icd10cm2014_pc} \code{get_icd10cm2015_pc} 19 | \code{get_icd10cm2016_pc} \code{get_icd10cm2017_pc} 20 | \code{get_icd10cm2018_pc} 21 | \url{https://www.cms.gov/Medicare/Coding/ICD10/downloads/pcs_refman.pdf} 22 | } 23 | \keyword{datasets} 24 | -------------------------------------------------------------------------------- /tests/testthat/test-build-maps-icd9-notquan.R: -------------------------------------------------------------------------------- 1 | context("build icd9 maps notquan") 2 | 3 | skip_slow("Skipping slow re-building of ICD-9 comorbidity maps (not quan)") 4 | 5 | test_that("ahrq icd9 map recreated", { 6 | skip_no_icd_data_raw( 7 | icd9_fetch_ahrq_sas, 8 | "comformat2012-2013 must be downloaded with icd9_fetch_ahrq_sas()" 9 | ) 10 | # same but from source data. Should be absolutely identical. 11 | expect_identical( 12 | result <- icd9_parse_ahrq_sas(save_pkg_data = FALSE), icd9_map_ahrq 13 | ) 14 | expect_is(result, "list") 15 | expect_equal(length(result), 30) 16 | expect_equivalent(get_invalid.comorbidity_map(icd9_map_ahrq), list()) 17 | }) 18 | 19 | test_that("Elixhauser icd9 map generated = saved", { 20 | expect_equivalent( 21 | icd9_map_elix, 22 | icd9_generate_map_elix(save_pkg_data = FALSE) 23 | ) 24 | expect_equivalent( 25 | get_invalid.comorbidity_map(icd9_map_elix, short_code = TRUE), 26 | list() 27 | ) 28 | }) 29 | -------------------------------------------------------------------------------- /tools/env/rhub-san: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #shellcheck disable=SC2034 3 | # 4 | # 5 | # 6 | _R_CHECK_COMPACT_DATA_=FALSE 7 | _R_CHECK_COMPILATION_FLAGS_=FALSE 8 | _R_CHECK_CRAN_INCOMING_=FALSE 9 | _R_CHECK_CRAN_INCOMING_REMOTE_=FALSE 10 | _R_CHECK_DEPRECATED_DEFUNCT_=FALSE 11 | _R_CHECK_DOC_SIZES2_=FALSE 12 | _R_CHECK_DOC_SIZES_=FALSE 13 | _R_CHECK_DOT_FIRSTLIB_=FALSE 14 | _R_CHECK_EXECUTABLES_EXCLUSIONS_=FALSE 15 | _R_CHECK_EXIT_ON_FIRST_ERROR_=FALSE 16 | _R_CHECK_INSTALL_DEPENDS_=FALSE 17 | _R_CHECK_NO_RECOMMENDED_=FALSE 18 | _R_CHECK_NO_STOP_ON_TEST_ERROR_=FALSE 19 | _R_CHECK_OVERWRITE_REGISTERED_S3_METHODS_=FALSE 20 | _R_CHECK_PKG_SIZES_=FALSE 21 | _R_CHECK_S3_METHODS_NOT_REGISTERED_=TRUE 22 | CXX11="g++ -std=c++11" 23 | CXX="g++ -std=c++11" 24 | GNUMAKEFLAGS="CXX11FLAGS+=-std=c++11\\ -Wno-ignored-attributes CXXFLAGS+=-std=c++11\\ -Wno-ignored-attributes" 25 | ICD_TEST_SLOW=TRUE 26 | MAKEFLAGS="CXX11FLAGS+=-std=c++11\\ -Wno-ignored-attributes CXXFLAGS+=-std=c++11\\ -Wno-ignored-attributes" 27 | -------------------------------------------------------------------------------- /tests/testthat/test-chapters-to-map.R: -------------------------------------------------------------------------------- 1 | context("chapter to map") 2 | 3 | skip_slow("chapters to map") 4 | 5 | test_that("chapters to map", { 6 | # Slow for huge chapters, like II (Cancer) 7 | n <- 3:6 8 | codes <- icd:::get_one_of_each()[n] 9 | ooe <- icd_long_data( 10 | visit_id = sprintf("pt%02d", n), 11 | code = codes, 12 | stringsAsFactors = TRUE 13 | ) 14 | class(ooe[["code"]]) <- c("icd9", "icd_decimal_diag", "factor") 15 | expect_warning( 16 | test_map <- chapters_to_map( 17 | .get_lazy("icd9_chapters")[n], 18 | defined = FALSE 19 | ), 20 | regexp = NA 21 | ) 22 | expect_warning( 23 | cmb <- icd9_comorbid( 24 | x = ooe, 25 | short_code = FALSE, 26 | map = test_map, 27 | short_map = TRUE, 28 | return_df = TRUE 29 | ), 30 | regexp = NA 31 | ) 32 | cmbcmp <- unname(as.matrix(logical_to_binary(cmb)[-1])) 33 | expmat <- diag(nrow = length(ooe$code)) 34 | expect_equivalent(cmbcmp, expmat) 35 | }) 36 | -------------------------------------------------------------------------------- /man/chapters_to_map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/convert.R 3 | \name{chapters_to_map} 4 | \alias{chapters_to_map} 5 | \title{Convert chapters to lists of codes for use as a comorbidity map} 6 | \usage{ 7 | chapters_to_map(x, defined = TRUE) 8 | } 9 | \arguments{ 10 | \item{x}{Either a chapter list itself, or the name of one, e.g. 11 | \code{icd9_sub_chapters}} 12 | 13 | \item{defined}{Single logical value, if \code{TRUE}, the default, only 14 | officially defined ICD-9 (currently ICD-9-CM) codes will be used in the 15 | expansion, not any syntactically possible ICD-9 code.} 16 | } 17 | \description{ 18 | The chapter headings can be converted into the full set of their children, 19 | and then used to look-up which chapter, sub-chapter, or 'major' a given code 20 | belongs. Always returns a map with short-form ICD-9 codes. These can be 21 | converted in bulk with \code{lapply} and \code{short_to_decimal}. 22 | } 23 | \keyword{internal} 24 | \keyword{manip} 25 | -------------------------------------------------------------------------------- /tools/check-quick.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #shellcheck disable=SC2012 3 | set -eu 4 | IFS=$'\n\t' 5 | ICD_HOME="${ICD_HOME:-${HOME}/icd}" 6 | 7 | tmpd="$(mktemp -d "/tmp/${0##*/}.XXXXXXXXXXX")" 8 | function finish { 9 | # rm -rf "$tmpd" 10 | echo "Finished with $tmpd" 11 | } 12 | trap finish EXIT 13 | #rsync -r --exclude=".git" "${ICD_HOME:-$HOME/rprojects/icd}" "$tmpd" 14 | cd "$tmpd" 15 | "${ICD_HOME}/tools/build-quick.sh" 16 | 17 | # try to unset debug flag, so ccache caches the results regardless of original path, 18 | # or configure ccache to do this 19 | 20 | # for all environment variable options see here: 21 | # https://cran.r-project.org/doc/manuals/r-release/R-ints.html#Tools 22 | # R_MAKEVARS_USER="$HOME/.R/Makevars.mac.quick" \ 23 | tarball="$(ls -t "$tmpd"/icd*.tar.gz | head -1)" 24 | R_CHECK_ENVIRON="${ICD_HOME}/tools/env/quick" \ 25 | R_MAKEVARS_USER=${HOME}/.R/Makevars.quick \ 26 | R CMD check \ 27 | --no-build-vignettes \ 28 | --ignore-vignettes \ 29 | "${tarball}" 30 | -------------------------------------------------------------------------------- /man/get_icd10cm_version.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/icd-cm-ver.R 3 | \name{get_icd10cm_version} 4 | \alias{get_icd10cm_version} 5 | \alias{get_icd10cm_active} 6 | \title{Get the data for a given version (four-digit year) of ICD-10-CM} 7 | \usage{ 8 | get_icd10cm_version(ver) 9 | 10 | get_icd10cm_active() 11 | } 12 | \arguments{ 13 | \item{ver}{Character vector of length one: the version of ICD-10-CM to use, 14 | corresponding to the suffix of the \code{data.frame} name, e.g., for 2019 15 | ICD-10-CM, use \code{"icd10cm2019"} for Dutch 2014 ICD-CM translations, use 16 | \code{"icd10cm2014_nl"}} 17 | } 18 | \description{ 19 | When called without an argument, it returns the currently active version as 20 | set by \code{set_icd10cm_active_year()} 21 | } 22 | \section{Functions}{ 23 | \itemize{ 24 | \item \code{get_icd10cm_active}: Get the currently active version of 25 | ICD-10-CM. 26 | }} 27 | 28 | \examples{ 29 | \dontrun{ 30 | get_icd10cm_version("2018") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /man/icd10_sub_chapters.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \name{icd10_sub_chapters} 4 | \alias{icd10_sub_chapters} 5 | \alias{icd10_sub_chapters_fr} 6 | \title{ICD-10 sub-chapters} 7 | \source{ 8 | http://apps.who.int/classifications/icd10/browse/2016/en 9 | } 10 | \description{ 11 | The WHO ICD-10 scheme sub-chapters. N.b. there may be WHO vs CM differences: 12 | please file bug if noted. In the \code{XML} definition of ICD-10-CM there are 13 | some intermediate hierarchical levels, e.g. for neoplasms. Sub-chapter here 14 | is defined as the lowest-level grouping of three-digit codes, e.g. C00-C14 15 | "Malignant neoplasms of lip, oral cavity and pharynx", not C00-C96 "Malignant 16 | neoplasms" which itself is a subset of the chapter C00-D49 "Neoplasms" 17 | } 18 | \details{ 19 | Format: list with sub-chapter or major names stored in list names, 20 | each with two element named character vector with start and end codes. 21 | } 22 | \seealso{ 23 | \code{\link{icd10_chapters}} 24 | } 25 | -------------------------------------------------------------------------------- /man/print.comorbidity_map.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/print.icd_comorbidity_map.R 3 | \name{print.comorbidity_map} 4 | \alias{print.comorbidity_map} 5 | \title{Print a comorbidity map} 6 | \usage{ 7 | \method{print}{comorbidity_map}(x, ..., n_comorbidities = 7, n_codes = 7) 8 | } 9 | \arguments{ 10 | \item{x}{a list optionally with class \code{comorbidity_map}} 11 | 12 | \item{...}{further arguments are passed to \code{print}} 13 | 14 | \item{n_comorbidities}{single integer, number of comorbidities to print} 15 | 16 | \item{n_codes}{single integer, number of codes per comorbidity to print} 17 | } 18 | \description{ 19 | The default is to summarize by printing the first seven comorbidities, and 20 | the first seven codes for each. To print the whole thing, just convert it to 21 | a list. 22 | } 23 | \examples{ 24 | icd9_map_ahrq 25 | \dontrun{ 26 | print(icd9_map_ahrq) 27 | print(icd9_map_ahrq, n_comorbidities = 3, n_codes = 3) 28 | print(unclass(icd9_map_ahrq)) 29 | } 30 | } 31 | \keyword{internal} 32 | -------------------------------------------------------------------------------- /src/attr.cpp: -------------------------------------------------------------------------------- 1 | #include "attr.hpp" 2 | #include "icd_types.hpp" 3 | using namespace Rcpp; 4 | 5 | //' Set ICD short-form diagnosis code attribute 6 | //' 7 | //' Doing this in an R function doesn't work for 'void' equivalent, and does a 8 | //' copy if the updated object is returned. 9 | //' @examples 10 | //' j <- "100" 11 | //' attr(j, "icd_short_diag") <- TRUE 12 | //' j 13 | //' attr(j, "icd_short_diag") <- FALSE 14 | //' j 15 | //' icd:::attr_decimal_diag(j) 16 | //' as.decimal_diag(j) 17 | //' # if pryr is installed, use address and refs to see what is going on 18 | //' @keywords internal attribute 19 | // [[Rcpp::export(attr_decimal_diag)]] 20 | void setDecimalDiag(RObject &x, bool value = true) { 21 | x.attr("icd_short_diag") = !value; 22 | } 23 | 24 | //' Set short diagnosis flag in C++ 25 | //' @param x Any R object 26 | //' @param value \code{TRUE} or \code{FALSE} 27 | //' @keywords internal attribute 28 | // [[Rcpp::export(attr_short_diag)]] 29 | void setShortDiag(RObject &x, bool value = true) { 30 | x.attr("icd_short_diag") = value; 31 | } 32 | -------------------------------------------------------------------------------- /man/get_defined.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/real.R 3 | \name{get_defined} 4 | \alias{get_defined} 5 | \title{Select only defined ICD codes} 6 | \usage{ 7 | get_defined(x, short_code = guess_short(x), billable = FALSE, leaf = billable) 8 | } 9 | \arguments{ 10 | \item{x}{input vector or factor, possibly with an ICD class} 11 | 12 | \item{short_code}{logical value, whether short-form ICD code} 13 | 14 | \item{billable}{single logical value, identical to 'leaf'. Leaf is preferred 15 | as most adaptations of WHO ICD codes are not oriented around money.} 16 | 17 | \item{leaf}{single logical value, whether to limit return codes also by 18 | whether they are billable, i.e. leaf nodes. This is really only designed 19 | for use with ICD-9-CM, ICD-10-CM etc, since the WHO versions are not 20 | designed for billing, but for public health and death reporting.} 21 | } 22 | \description{ 23 | Return only those codes which are heading or leaf (billable), specifying 24 | whether codes are all short-form or all decimal-form 25 | } 26 | -------------------------------------------------------------------------------- /src/appendMinor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef APPENDMINOR_H_ 2 | #define APPENDMINOR_H_ 3 | 4 | #include "icd_types.hpp" 5 | CV icd9MajMinToCode(const CV& mjr, 6 | const CV& mnr, 7 | const bool isShort); 8 | CV icd9MajMinToShort(const CV& mjr, const CV& mnr); 9 | CV icd9MajMinToDecimal(const CV mjr, const CV mnr); 10 | void icd9AppendMinors(VecStr &m, const VecStr &mnr, bool isShort); 11 | 12 | inline void icd9AppendMinorsShort(std::vector& m, 13 | const std::vector& mnr) { 14 | for (std::vector::size_type j = 0; j != m.size(); ++j) { 15 | m[j].append(mnr[j]); 16 | } 17 | } 18 | 19 | inline void icd9AppendMinorsShort(std::vector& m, 20 | const std::vector& mnr, 21 | bool reserve) { 22 | if (reserve) m.reserve(5); 23 | for (std::vector::size_type j = 0; j != m.size(); ++j) { 24 | m[j].append(mnr[j]); 25 | } 26 | } 27 | 28 | #endif /* APPENDMINOR_H_ */ 29 | -------------------------------------------------------------------------------- /man/download_all_icd_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/options.R 3 | \name{download_all_icd_data} 4 | \alias{download_all_icd_data} 5 | \title{Download all the additional data at once} 6 | \usage{ 7 | download_all_icd_data() 8 | } 9 | \description{ 10 | It will download and parse WHO ICD-10, French, and Belgian codes and 11 | descriptions. It will also get years 2014, 2015, 2017, and 2018 for ICD-10-CM 12 | (diagnostic codes), and 2014--2019 procedure codes. 2016 and 2019 diagnostic 13 | codes are included in the package data. The total amount of data is about 14 | 340Mb. It is not necessary to do call \code{download_all_icd_data} for normal 15 | use: you may simply call the functions like \code{get_icd10cm2014}, which 16 | will download data when needed. 17 | } 18 | \examples{ 19 | \dontrun{ 20 | # set_icd_data_dir() 21 | # set_icd_data_dir("/tmp/icd") 22 | 23 | # The following would download, and make all the known ICD data available 24 | # download_all_icd_data() 25 | } 26 | } 27 | \seealso{ 28 | \code{\link{set_icd_data_dir}} 29 | } 30 | -------------------------------------------------------------------------------- /man/guess_version.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/guess.R 3 | \name{guess_version} 4 | \alias{guess_version} 5 | \title{Guess version of ICD codes} 6 | \usage{ 7 | guess_version(x, short_code, ...) 8 | } 9 | \arguments{ 10 | \item{x}{input data} 11 | 12 | \item{short_code}{single logical value which determines whether the ICD-9 13 | code provided is in short (\code{TRUE}) or decimal (\code{FALSE}) form. 14 | Where reasonable, this is guessed from the input data.} 15 | 16 | \item{n}{number of elements or rows to sample} 17 | } 18 | \description{ 19 | The guess is indeed a guess and can be wrong. There are some codes which 20 | could be either ICD-9 or ICD-10. The current implementation doesn't check 21 | whether the codes exist in any definitions (ICD-9 CM or WHO, for example), 22 | just whether they are valid. 23 | } 24 | \details{ 25 | Currently, ambiguous codes are guessed as being ICD-9 or ICD-10, with no 26 | indication of uncertainty. Possible solutions are adding an attribute, 27 | warning, or optionally throwing an error. 28 | } 29 | \keyword{internal} 30 | -------------------------------------------------------------------------------- /man/icd10_chapters.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{icd10_chapters} 5 | \alias{icd10_chapters} 6 | \alias{icd10_chapters_fr} 7 | \title{ICD-10 chapters} 8 | \source{ 9 | http://apps.who.int/classifications/icd10/browse/2016/en 10 | } 11 | \description{ 12 | The WHO ICD-10 scheme chapters. The chapter level is the highest in the 13 | hierarchy, each chapter containing sets of codes which span multiple 14 | three-digit 'major' codes, and in some cases also span codes across two 15 | alphabetic initial characters. E.g. Chapter I spans A00 to B99. 16 | } 17 | \details{ 18 | 2017 ICD-10-CM does not have any U codes (codes for special purposes). 19 | U00-U49 - Provisional assignment of new diseases of uncertain etiology or 20 | emergency use U82-U85 - Resistance to antimicrobial and anti-neoplastic drugs 21 | 22 | Format: list with chapter names stored in list names, each with two 23 | element named character vector with start and end codes. 24 | } 25 | \seealso{ 26 | \code{\link{icd10_sub_chapters}} 27 | } 28 | \keyword{datasets} 29 | -------------------------------------------------------------------------------- /man/get_icd10fr2019.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10fr2019} 5 | \alias{get_icd10fr2019} 6 | \title{French ICD-10-FR modification of WHO ICD-10 used in France} 7 | \source{ 8 | \url{https://www.atih.sante.fr/cim-10-fr-2018-usage-pmsi} 9 | } 10 | \description{ 11 | La Classification internationale statistique des maladies (CIM), version 10, 12 | edition française (The International Classification of Diseases (ICD), 13 | version 10, French edition.) Comme la version américaine, l'édition française 14 | a beaucoup de changéements par rapport à l'édition de l'OMS. Juste l'année 15 | 2018 est présentée pour le moment. 16 | The short descriptions are capitalized, and, as is correct in French, do not 17 | require accents. These were not converted to lower or sentence case to avoid 18 | introducing spelling errors. 19 | Définitions CIM-10-FR de l'OMS (WHO ICD-10 definitions) 20 | } 21 | \references{ 22 | \href{https://www.atih.sante.fr/nomenclatures-de-recueil-de-linformation/cim}{ATIH 23 | CIM-10-FR} 24 | } 25 | \keyword{datasets} 26 | -------------------------------------------------------------------------------- /man/convert.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/convert.R 3 | \name{convert} 4 | \alias{convert} 5 | \title{Convert ICD data between formats and structures.} 6 | \description{ 7 | ICD codes are represented in \emph{short} and \emph{decimal} forms. The 8 | short form has up to 5 digits, or V or E followed by up to four digits. The 9 | decimal form has a decimal point to delimit the top-level (henceforth 10 | \emph{major}) category, and the \emph{minor} part containing the subsidiary 11 | classifications. 12 | } 13 | \details{ 14 | For conversions of ICD-9 or ICD-10 codes between the \emph{short} and 15 | \emph{decimal} forms, use \code{\link{short_to_decimal}} and 16 | \code{\link{decimal_to_short}}. 17 | 18 | \pkg{icd} does not covert ICD-9 to ICD-10 codes yet. 19 | } 20 | \seealso{ 21 | Other ICD data conversion: 22 | \code{\link{comorbid_df_to_mat}()}, 23 | \code{\link{comorbid_mat_to_df}()}, 24 | \code{\link{decimal_to_short}()}, 25 | \code{\link{long_to_wide}()}, 26 | \code{\link{short_to_decimal}()}, 27 | \code{\link{wide_to_long}()} 28 | } 29 | \concept{ICD data conversion} 30 | -------------------------------------------------------------------------------- /man/is.icd9.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class.R 3 | \name{is.icd9} 4 | \alias{is.icd9} 5 | \alias{is.icd9cm} 6 | \alias{is.icd9cm_pc} 7 | \alias{is.icd9who} 8 | \alias{is.icd10} 9 | \alias{is.icd10cm} 10 | \alias{is.icd10cm_pc} 11 | \alias{is.icd10who} 12 | \alias{is.icd10fr} 13 | \alias{is.icd10be} 14 | \alias{is.comorbidity_map} 15 | \title{Test presence of ICD classes} 16 | \usage{ 17 | is.icd9(x) 18 | 19 | is.icd9cm(x) 20 | 21 | is.icd9cm_pc(x) 22 | 23 | is.icd9who(x) 24 | 25 | is.icd10(x) 26 | 27 | is.icd10cm(x) 28 | 29 | is.icd10cm_pc(x) 30 | 31 | is.icd10who(x) 32 | 33 | is.icd10fr(x) 34 | 35 | is.icd10be(x) 36 | 37 | is.comorbidity_map(x) 38 | } 39 | \arguments{ 40 | \item{x}{Any object which may have ICD-related classes set} 41 | } 42 | \description{ 43 | This merely checks whether the given object is a certain type of ICD code, it 44 | does no validation of any kind. For validation, see \code{\link{is_valid}}. 45 | } 46 | \examples{ 47 | # A character string is not itself an ICD code 48 | is.icd9("100.1") 49 | is_valid("100.1") 50 | is.icd9(as.icd9cm("100.1")) 51 | } 52 | -------------------------------------------------------------------------------- /man/get_icd10be2014.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd10be2014} 5 | \alias{get_icd10be2014} 6 | \title{Belgian ICD-10-BE} 7 | \source{ 8 | \url{https://www.health.belgium.be/en/node/30433} 9 | \url{https://www.health.belgium.be/sites/default/files/uploads/fields/fpshealth_theme_file/fy2017_reflist_icd-10-be.xlsx_last_updatet_28-07-2017_1.xlsx} 10 | \url{https://www.health.belgium.be/fr/sante/organisation-des-soins-de-sante/hopitaux/systemes-denregistrement/icd-10-be} 11 | \url{https://www.health.belgium.be/fr/fy2014reflisticd-10-bexlsx} 12 | } 13 | \description{ 14 | This is based heavily on ICD-10-CM. 2014 is identical, with translations for 15 | most of the codes into Dutch and French. 2017 has about a hundred additional 16 | code definitions over ICD-10-CM 2017. The 2014 data also has the interesting 17 | fields for gender specificity of a given code, and whether it is permissible 18 | as Present-on-Arrival (POA). 19 | } 20 | \seealso{ 21 | \code{\link{get_icd10be2017}} \code{\link{get_icd10be2014_pc}} 22 | \code{\link{get_icd10be2017_pc}} 23 | } 24 | \keyword{datasets} 25 | -------------------------------------------------------------------------------- /src/util.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H_ 2 | #define UTIL_H_ 3 | 4 | #include "icd_types.hpp" 5 | #include "local.hpp" 6 | #include // for pair 7 | 8 | std::string trimLeftCpp(std::string s); 9 | std::string strimCpp(std::string s); 10 | bool strVecEqual(Rcpp::CharacterVector x, Rcpp::CharacterVector y); 11 | Rcpp::CharacterVector icd10cmSort(const Rcpp::CharacterVector &x); 12 | Rcpp::IntegerVector icd10cmOrder(const Rcpp::CharacterVector &x); 13 | // concatenate a vector of vectors 14 | template 15 | void my_concat(COCiter start, COCiter end, Oiter dest) { 16 | while (start != end) { 17 | dest = std::copy(start->begin(), start->end(), dest); 18 | ++start; 19 | } 20 | } 21 | 22 | inline Rcpp::CharacterVector getDataFrameStringRow( 23 | const Rcpp::DataFrame &df, const R_xlen_t i, const R_xlen_t start_idx = 0) { 24 | Rcpp::CharacterVector out; 25 | const auto dfCols = df.size(); 26 | for (R_xlen_t j = start_idx; j != dfCols; ++j) { 27 | const Rcpp::CharacterVector &col = df(j); 28 | const Rcpp::String s = col(i); 29 | out.push_back(s); 30 | } 31 | return out; 32 | } 33 | #endif /* UTIL_H_ */ 34 | -------------------------------------------------------------------------------- /man/guess_short.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R 3 | \name{guess_short} 4 | \alias{guess_short} 5 | \title{Guess whether codes are \code{short_code} or \code{decimal_code}} 6 | \usage{ 7 | guess_short(x_, short_code = NULL, n = 1000L, icd_name = NULL) 8 | } 9 | \value{ 10 | single logical value, \code{TRUE} if input data are predominantly 11 | \code{short_code} type. If there is some uncertainty, then return 12 | \code{NA}. 13 | } 14 | \description{ 15 | The goal is to guess whether codes are \code{short_code} or 16 | \code{decimal_code} form. Currently condense works, but not with the 17 | \code{icd} look-up table currently in use. Of note, validation is a bit 18 | different here, since we don't know the type until after we guess. We could 19 | look for where both short_code and long are invalid, and otherwise assume 20 | valid, even if the bulk are short_code. However, it may be more useful to 21 | check validity after the guess. 22 | } 23 | \details{ 24 | Very quick heuristic, ploughs through ten million codes in less 25 | than one second and will stop more quickly if it finds a '.'. 26 | } 27 | \keyword{internal} 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.un~ 2 | *.bak 3 | *.dll 4 | *.gcno 5 | *.md 6 | *.o 7 | *.so 8 | *.swp 9 | *.xcworkspace 10 | .DS_Store 11 | .RData 12 | .Rhistory 13 | .Rprofile 14 | .Rproj.user 15 | .build.timestamp 16 | .checkpoint 17 | .cproject 18 | .externalToolBuilders 19 | .project 20 | .settings 21 | Meta 22 | README.html 23 | Rplot.png 24 | Rprof.out 25 | aclocal.m4 26 | autom4te.cache 27 | autoscan.log 28 | bench-versus-result*.rds 29 | callgrind.* 30 | ccache.log 31 | confdefs.h 32 | config.log 33 | config.status 34 | configure.scan 35 | conftest.* 36 | conftest.c 37 | conftest.cpp 38 | conftest.err 39 | doc 40 | docs 41 | i9test.RData 42 | icd-*build.log 43 | icd.Rcheck 44 | icd10cm_codes_2017.txt 45 | icd10cm_codes_2018.txt 46 | icd9_*.tar.gz 47 | icd_*.tar.gz 48 | include-dependencies 49 | include-dependencies.d 50 | inst/doc 51 | inst/doc/* 52 | revdep 53 | rprof.out 54 | src-i386 55 | src-x64 56 | src/*.o.tmp 57 | src/makevars.h 58 | test-all-disabled.R 59 | tests/testthat-split-*.R 60 | tests/testthat/Rplots.pdf 61 | testthat-disabled.R 62 | bench-refactor.html 63 | .gdb_history 64 | benchmarks/icd-JSS3447-replication/*.log 65 | .travis.yml.* 66 | travis-notes.txt 67 | .deps 68 | *build.log 69 | -------------------------------------------------------------------------------- /R/parse-icd10-pc.R: -------------------------------------------------------------------------------- 1 | 2 | .icd10cm_parse_cms_pcs_all <- function() { 3 | .msg("Parsing all ICD-10-CM procedure codes") 4 | lapply( 5 | names(.icd10cm_sources), 6 | .icd10cm_parse_cms_pcs_year 7 | ) 8 | invisible() 9 | } 10 | 11 | .icd10cm_parse_cms_pcs_year <- function(year, 12 | must_work = FALSE) { 13 | year <- as.character(year) 14 | pcs_file <- .icd10cm_sources[[year]][["pcs_flat"]] 15 | pcs_path <- file.path( 16 | get_icd_data_dir(), 17 | .get_versioned_raw_file_name(pcs_file, ver = year) 18 | ) 19 | out <- utils::read.fwf(pcs_path, c(5, 8, 2, 62, 120), 20 | header = FALSE, 21 | col.names = c( 22 | "count", 23 | "code", 24 | "leaf", 25 | "short_desc", 26 | "long_desc" 27 | ) 28 | ) 29 | out$count <- NULL 30 | out$code <- trimws(as.character(out$code)) 31 | out$leaf <- as.logical(out$leaf) 32 | out$short_desc <- trimws(as.character(out$short_desc)) 33 | out$long_desc <- trimws(as.character(out$long_desc)) 34 | out <- out[order(out$code), ] 35 | var_name <- paste0("icd10cm", year, "_pc") 36 | .save_in_cache(var_name = var_name, x = out) 37 | invisible(out) 38 | } 39 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | Re-submission, with corrected links in documentation, and package sized reduced under 5 Mb as requested by Dr. Ligges. With apologies for inability to fix the check warnings for compiler flags and documentation. I have now Removed deprecated CPP flag as requested. Fixed new documentation-related warnings from CRAN. Thanks for your work. 2 | 3 | # Test environments 4 | 5 | * Ubuntu 19.04 R 3.6.3, clang 9, gcc 9, clang 10, gcc 10 6 | * Travis CI: MacOS, Ubuntu 16.04, 18.04 (Travis) R-devel, R-release, gcc, clang 7 | * Windows Server 2012 R2 x64 (Appveyor), R devel 32 and 64 bit 8 | * MacOS Mojave 10.14.16, R 4.0.0, brew clang 9 9 | 10 | # R CMD check results 11 | 12 | Sometimes I get a URL download fail for the URL http://ftp.cdc.gov/pub/Health_Statistics/NCHS/Publications/ICD9-CM/2011/Dtab12.zip which is in a man page. The problem is that the http site directs to https sometimes, and then on some platforms has a certificate error. The URL is valid. 13 | 14 | There is one note: 15 | 16 | * checking data for non-ASCII characters ... NOTE 17 | Note: found 20 marked UTF-8 strings 18 | 19 | These are from accented characters in the US disease name definitions for ICD-9-CM and ICD-10-CM. 20 | -------------------------------------------------------------------------------- /man/expand_range_major.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ranges.R 3 | \name{expand_range_major} 4 | \alias{expand_range_major} 5 | \alias{expand_range_major.default} 6 | \alias{expand_range_major.icd10cm} 7 | \alias{expand_range_major.icd9} 8 | \title{Expand two major codes to a range} 9 | \usage{ 10 | expand_range_major(start, end, defined = TRUE) 11 | 12 | \method{expand_range_major}{default}(start, end, defined = TRUE) 13 | 14 | \method{expand_range_major}{icd10cm}(start, end, defined = TRUE) 15 | 16 | \method{expand_range_major}{icd9}(start, end, defined = TRUE) 17 | } 18 | \arguments{ 19 | \item{...}{arguments passed on to other functions} 20 | } 21 | \description{ 22 | Expand a pair of major codes into a range of major codes. 23 | } 24 | \details{ 25 | Primarily for internal use 26 | } 27 | \section{Methods (by class)}{ 28 | \itemize{ 29 | \item \code{default}: Expand range of top-level, 'major' codes 30 | of unknown type 31 | 32 | \item \code{icd10cm}: Expand range of top-level ICD-10 codes 33 | 34 | \item \code{icd9}: Expand a range of ICD-9 major codes into 35 | major codes 36 | }} 37 | 38 | \examples{ 39 | expand_range_major("100", "102") 40 | } 41 | \keyword{internal} 42 | -------------------------------------------------------------------------------- /benchmarks/bench-fill-integer-seq-duff.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | 5 | // Duff's device for 0..n sequence, for fun. 6 | // [[Rcpp::export]] 7 | std::vector seqZero(const int n) { 8 | const int m = n + 1; 9 | std::vector out; 10 | out.reserve(m); 11 | int c = 0; 12 | { 13 | int nl = (m + 7) / 8; 14 | switch(m % 8) { 15 | case 0: do { out.emplace_back(c++); 16 | case 7: out.emplace_back(c++); 17 | case 6: out.emplace_back(c++); 18 | case 5: out.emplace_back(c++); 19 | case 4: out.emplace_back(c++); 20 | case 3: out.emplace_back(c++); 21 | case 2: out.emplace_back(c++); 22 | case 1: out.emplace_back(c++); 23 | } while(--nl != 0); 24 | } 25 | } 26 | return out; 27 | } 28 | 29 | // [[Rcpp::export]] 30 | std::vector seqZeroLoop(const int n) { 31 | std::vector out; 32 | const int m = n + 1; 33 | out.reserve(m); 34 | for (int i = 0; i != m; ++i) { 35 | out.emplace_back(i); 36 | } 37 | return out; 38 | } 39 | 40 | 41 | /***R 42 | # This is slower with -O2, and more so with -O3 even with -fno-unroll-loops 43 | bench::press(n = c(100, 1e6, 1e7, 1e8), { 44 | bench::mark(seqZero(n), seqZeroLoop(n)) 45 | }) 46 | */ 47 | -------------------------------------------------------------------------------- /tests/testthat/test-build-maps-icd10.R: -------------------------------------------------------------------------------- 1 | context("build icd10 maps") 2 | 3 | test_that("the icd-10 quan elix comorbidity map is reproduced", { 4 | skip_multi() 5 | expect_equivalent( 6 | icd10_map_quan_elix, 7 | icd10_generate_map_quan_elix(save_pkg_data = FALSE) 8 | ) 9 | }) 10 | 11 | test_that("the icd-10 quan deyo comorbidity map is reproduced", { 12 | skip_multi() 13 | expect_equivalent( 14 | icd10_map_quan_deyo, 15 | icd10_generate_map_quan_deyo(save_pkg_data = FALSE) 16 | ) 17 | }) 18 | 19 | test_that("the icd-10 elix comorbidity map is reproduced", { 20 | skip_multi() 21 | expect_equivalent( 22 | icd10_map_elix, 23 | icd10_generate_map_elix(save_pkg_data = FALSE) 24 | ) 25 | expect_equivalent( 26 | get_invalid.comorbidity_map(icd10_map_elix, short_code = TRUE), list() 27 | ) 28 | }) 29 | 30 | test_that("icd-10 ahrq map is reproduced", { 31 | skip_if_offline() 32 | skip_on_appveyor() 33 | skip_on_travis() 34 | skip_on_cran() 35 | skip_no_icd_data_raw( 36 | icd10_fetch_ahrq_sas, 37 | "AHRQ ICD-10 SAS must be downloaded with icd10_fetch_ahrq_sas" 38 | ) 39 | expect_equivalent( 40 | icd10_map_ahrq, 41 | icd10_parse_ahrq_sas(save_pkg_data = FALSE) 42 | ) 43 | }) 44 | -------------------------------------------------------------------------------- /man/get_invalid.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/valid.R 3 | \name{get_invalid} 4 | \alias{get_invalid} 5 | \alias{get_invalid.default} 6 | \alias{get_invalid.icd9} 7 | \alias{get_invalid.icd10} 8 | \alias{get_invalid.comorbidity_map} 9 | \title{Get invalid ICD codes} 10 | \usage{ 11 | get_invalid(...) 12 | 13 | \method{get_invalid}{default}(x, short_code = guess_short(x), ...) 14 | 15 | \method{get_invalid}{icd9}(x, short_code = guess_short(x), ...) 16 | 17 | \method{get_invalid}{icd10}(x, short_code = guess_short(x), ...) 18 | 19 | \method{get_invalid}{comorbidity_map}(x, short_code = guess_short(x), ...) 20 | } 21 | \arguments{ 22 | \item{x}{vector of ICD codes, or list of vectors of ICD codes forming a 23 | comorbidity map} 24 | } 25 | \description{ 26 | Returns subset of codes which are not in valid short_code or 27 | decimal format. 28 | } 29 | \section{Methods (by class)}{ 30 | \itemize{ 31 | \item \code{default}: Default method when ICD version or short versus 32 | decimal not known. 33 | 34 | \item \code{icd9}: Get invalid ICD-9 codes from vector of codes 35 | 36 | \item \code{icd10}: Get invalid ICD-10 codes from vector of codes 37 | 38 | \item \code{comorbidity_map}: Get invalid elements of a comorbidity map 39 | }} 40 | 41 | \keyword{internal} 42 | -------------------------------------------------------------------------------- /man/print.icd9.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class.R 3 | \name{print.icd9} 4 | \alias{print.icd9} 5 | \alias{print.icd10} 6 | \title{Print ICD codes and comorbidity maps cleanly} 7 | \usage{ 8 | \method{print}{icd9}(x, verbose = FALSE, ...) 9 | 10 | \method{print}{icd10}(x, verbose = FALSE, ...) 11 | } 12 | \arguments{ 13 | \item{x}{ICD codes to be printed} 14 | 15 | \item{verbose}{Annotate based on code attributes, e.g., decimal versus short 16 | codes.} 17 | 18 | \item{...}{arguments passed on to other functions} 19 | } 20 | \description{ 21 | Print ICD codes and comorbidity maps cleanly 22 | } 23 | \examples{ 24 | x <- structure( 25 | c("40201", "2258", "7208", "25001", "34400", "4011", "4011", NA), 26 | class = c("icd9cm", "icd9", "character"), 27 | icd_short_diag = TRUE 28 | ) 29 | \dontrun{ 30 | print(x) 31 | print(x, verbose = TRUE) 32 | # as.factor drops any 'icd' classes 33 | print(as.factor(x), verbose = TRUE) 34 | } 35 | \dontrun{ 36 | u <- uranium_pathology[1:10, "icd10"] 37 | print(u) 38 | print(u, verbose = TRUE) 39 | # as.character will unclass the 'icd' classes 40 | print(as.character(u), verbose = TRUE) 41 | a <- structure(c("R21", "Z21"), 42 | class = c("icd10cm", "icd10", "character") 43 | ) 44 | print(a, verbose = TRUE) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/relevant.hpp: -------------------------------------------------------------------------------- 1 | #include "icd_types.hpp" 2 | #include "local.hpp" 3 | using namespace Rcpp; 4 | 5 | #ifndef RELEVANT_H_ 6 | #define RELEVANT_H_ 7 | 8 | class Relevant { 9 | private: 10 | US allCodesSet; 11 | US r; 12 | 13 | public: 14 | const List &src_map; 15 | const CV relevant; 16 | std::unordered_map rel; 17 | IHS hash; 18 | CV keys; 19 | // construct from a vector of codes only 20 | Relevant(const List &map, const SEXP &codes) 21 | : src_map(map), relevant(findRelevant(codes)), rel(findRel(relevant)), 22 | hash(IHS(relevant).fill()), keys(hash.keys()) {} 23 | // construct from a dataframe with given columns 24 | Relevant(const List &map, const List &data, const CV& code_names) 25 | : src_map(map), relevant(findRelevant(data, code_names)), 26 | rel(findRel(relevant)), hash(IHS(relevant).fill()), keys(hash.keys()) { 27 | } 28 | void buildCodeSetCV(const CV &codes); 29 | void buildCodeSetInt(const IntegerVector &codes); 30 | void buildCodeSet(const SEXP &codes); 31 | CV findRelevant(); 32 | CV findRelevant(const SEXP &codes); 33 | // CV findRelevant(const DataFrame& data, CV code_fields); 34 | CV findRelevant(const List &data, const CV& code_names); 35 | RelMap findRel(const CharacterVector& x); 36 | }; // Relevant 37 | 38 | #endif // RELEVANT_H_ 39 | -------------------------------------------------------------------------------- /man/generate_neds_pts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/util-test.R 3 | \name{generate_neds_pts} 4 | \alias{generate_neds_pts} 5 | \title{Generate simulated 'NEDS' data for 'PCCC' and bigger wide data testing} 6 | \usage{ 7 | generate_neds_pts(n = 1000L, ncol = 20L, icd10 = TRUE, verbose = FALSE) 8 | } 9 | \arguments{ 10 | \item{n}{Integer number of rows of data to generate} 11 | 12 | \item{ncol}{Integer number of diagnostic code columns, default of 20 matches 13 | NEDS} 14 | 15 | \item{icd10}{Logical, default \code{TRUE} to sample ICD-10-CM codes. 16 | \code{FALSE} gives \code{ICD-9}} 17 | 18 | \item{verbose}{single logical value, defaults to \code{FALSE} in most functions.} 19 | } 20 | \description{ 21 | Generate simulated 'NEDS' data for 'PCCC' and bigger wide data testing 22 | } 23 | \examples{ 24 | summary(icd::comorbid_pccc_dx(icd:::generate_neds_pts())) 25 | neds <- icd:::generate_neds_pts(n = 100, ncol = 10L, icd10 = FALSE) 26 | stopifnot(dim(neds) == c(100L, 11L)) 27 | summary(icd::comorbid_pccc_dx(neds)) 28 | \dontrun{ 29 | # original size data for PCCC benchmarking: 30 | set.seed(1441) 31 | # Large NEDS simulation: neds <- icd:::generate_neds_pts(28584301L) 32 | neds <- icd:::generate_neds_pts(2858L) 33 | neds_comorbid <- icd::comorbid_pccc_dx(neds) 34 | } 35 | } 36 | \keyword{internal} 37 | -------------------------------------------------------------------------------- /tests/testthat/test-longtowide.R: -------------------------------------------------------------------------------- 1 | context("compare ordered long to wide methods") 2 | 3 | pts <- generate_random_ordered_pts(5000, 13) 4 | 5 | test_that("ordered and unordered methods on ordered data are identical", { 6 | ord <- long_to_wide(pts) 7 | expect_true(all(ord$visit_id %in% pts$visit_id)) 8 | expect_true(all(pts$visit_id %in% ord$visit_id)) 9 | }) 10 | 11 | test_that("disordered rows", { 12 | df <- structure( 13 | list( 14 | visit_id = c("v2", "v4", "v3", "v2", "v2", "v4"), 15 | icd9 = structure(c("39891", "0932", "4151", "440", "4011", "4010"), 16 | class = c("icd9", "character") 17 | ) 18 | ), 19 | row.names = c(NA, 6L), 20 | class = c("icd_long_data", "data.frame") 21 | ) 22 | df_wide <- long_to_wide(df) 23 | expect_equivalent( 24 | long_to_wide(df), 25 | structure(list( 26 | visit_id = c("v2", "v3", "v4"), 27 | icd_001 = structure(c("39891", "4151", "0932"), 28 | class = c("icd9", "character") 29 | ), 30 | icd_002 = structure(c("440", NA, "4010"), 31 | class = c("icd9", "character") 32 | ), 33 | icd_003 = structure(c("4011", NA, NA), 34 | class = c("icd9", "character") 35 | ) 36 | ), 37 | row.names = c(1L, 3L, 2L), 38 | class = c("icd_wide_data", "icd_long_data", "data.frame") 39 | ) 40 | ) 41 | }) 42 | -------------------------------------------------------------------------------- /man/icd9MajMinToCode.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/RcppExports.R 3 | \name{icd9MajMinToCode} 4 | \alias{icd9MajMinToCode} 5 | \title{Convert \code{mjr} and \code{mnr} vectors to single code} 6 | \usage{ 7 | icd9MajMinToCode(mjr, mnr, isShort) 8 | } 9 | \arguments{ 10 | \item{isShort}{Deprecated. Single logical value which determines whether the 11 | ICD-9 code provided is in short (\code{TRUE}) or decimal (\code{FALSE}) 12 | form. Where reasonable, this is guessed from the input data. Use 13 | \code{short_code} instead.} 14 | 15 | \item{major}{character vector of 'major' part of ICD-9 codes, i.e. that part 16 | which falls before the decimal point, in decimal notation. (In five digit 17 | notation, the 'major' part is be the first three characters (with leading 18 | zeroes), and includes V or E prefix.} 19 | 20 | \item{minor}{character vector of 'minor' part of ICD-9 codes, i.e. that part 21 | which falls after the decimal point, in decimal notation. (In 'short' five 22 | digit notation, the 'major' part is the first three characters including 23 | leading zeroes which may be inferred; the last two characters represent the 24 | 'minor' part.)} 25 | } 26 | \value{ 27 | Character vector 28 | } 29 | \description{ 30 | Convert \code{mjr} and \code{mnr} vectors to single code 31 | } 32 | \keyword{internal} 33 | \keyword{manip} 34 | -------------------------------------------------------------------------------- /src/ranges.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RANGES_H_ 2 | #define RANGES_H_ 3 | 4 | #include "icd_types.hpp" 5 | #include "range-const.hpp" 6 | 7 | CV icd9ExpandMinor(const Str& mnr, 8 | bool isE = false); 9 | CV icd9ChildrenShortUndefined(const CV& icd9Short); 10 | CV icd9ChildrenShortDefined(const CV& icd9Short, 11 | const VecStr& icd9cmReal); 12 | CV icd9ChildrenShort(const CV& icd9Short, 13 | const VecStr& icd9cmReal, 14 | bool onlyReal = true); 15 | CV icd9ChildrenShortUnorderedUndefined(const CV& icd9Short); 16 | CV icd9ChildrenShortUnorderedDefined(const CV& icd9Short, 17 | const VecStr& icd9cmReal); 18 | CV icd9ChildrenShortUnordered(const CV& icd9Short, 19 | const VecStr& icd9cmReal, 20 | bool onlyReal = true); 21 | CV icd9ChildrenDecimal(const CV& icd9Decimal, 22 | const VecStr& icd9cmReal, 23 | bool onlyReal = true); 24 | CV icd9ChildrenDecimalUnordered(const CV& icd9Decimal, 25 | const VecStr& icd9cmReal, 26 | bool onlyReal); 27 | CV icd9Children(const CV& icd9, 28 | bool isShort, 29 | const VecStr& icd9cmReal, 30 | bool onlyReal = true); 31 | #endif /* RANGES_H_ */ 32 | -------------------------------------------------------------------------------- /src/range-const.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RANGE_CONST_H_ 2 | #define RANGE_CONST_H_ 3 | 4 | #include "icd_types.hpp" 5 | 6 | // this is simplest just to hard-code 7 | const CV vbase = 8 | CV::create("", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "00"); 9 | const CV vbase_e = 10 | CV::create("", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "00"); 11 | const CV v0 = 12 | CV::create("0", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09"); 13 | const CV v1 = 14 | CV::create("1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"); 15 | const CV v2 = 16 | CV::create("2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"); 17 | const CV v3 = 18 | CV::create("3", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39"); 19 | const CV v4 = 20 | CV::create("4", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49"); 21 | const CV v5 = 22 | CV::create("5", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59"); 23 | const CV v6 = 24 | CV::create("6", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69"); 25 | const CV v7 = 26 | CV::create("7", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79"); 27 | const CV v8 = 28 | CV::create("8", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89"); 29 | const CV v9 = 30 | CV::create("9", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"); 31 | 32 | #endif /* RANGE_CONST_H_ */ 33 | -------------------------------------------------------------------------------- /tools/env/quick: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #R_MAKEVARS_USER=${ICD_HOME}/tools/Makevars.quick - this then ignores ~/.R/Makevars.* 3 | #shellcheck disable=SC2034 4 | ICD_TEST_SLOW=FALSE 5 | ICD_OFFLINE=TRUE 6 | ICD_INTERACT=FALSE 7 | MAKEFLAGS=-j$(getconf _NPROCESSORS_ONLN) 8 | _R_CHECK_ALL_NON_ISO_C_=TRUE 9 | _R_CHECK_ASCII_DATA_=FALSE 10 | _R_CHECK_CODE_ASSIGN_TO_GLOBALENV_=TRUE 11 | _R_CHECK_CODE_ATTACH_=FALSE 12 | _R_CHECK_CODE_DATA_INTO_GLOBALENV_=TRUE 13 | _R_CHECK_CODE_USAGE_VIA_NAMESPACES_=TRUE 14 | _R_CHECK_CODETOOLS_PROFILE_="suppressLocalUnused=FALSE" 15 | _R_CHECK_COMPACT_DATA_=FALSE 16 | _R_CHECK_COMPILATION_FLAGS_=FALSE 17 | _R_CHECK_CRAN_INCOMING_=FALSE 18 | _R_CHECK_CRAN_INCOMING_REMOTE_=FALSE 19 | _R_CHECK_DEPRECATED_DEFUNCT_=FALSE 20 | _R_CHECK_DOC_SIZES2_=FALSE 21 | _R_CHECK_DOT_FIRSTLIB_=FALSE 22 | _R_CHECK_EXECUTABLES_EXCLUSIONS_=FALSE 23 | _R_CHECK_EXIT_ON_FIRST_ERROR_=TRUE 24 | _R_CHECK_INSTALL_DEPENDS_=FALSE 25 | _R_CHECK_LENGTH_1_CONDITION_="verbose,abort" 26 | _R_CHECK_LENGTH_1_LOGIC2_="verbose,abort" 27 | _R_CHECK_NATIVE_ROUTINE_REGISTRATION_=TRUE 28 | _R_CHECK_NO_RECOMMENDED_=FALSE 29 | _R_CHECK_NO_STOP_ON_TEST_ERROR_=FALSE 30 | _R_CHECK_OVERWRITE_REGISTERED_S3_METHODS_=FALSE 31 | _R_CHECK_PKG_SIZES_=FALSE 32 | _R_CHECK_RD_EXAMPLES_T_AND_F_=TRUE 33 | _R_CHECK_RD_LINE_WIDTHS_=TRUE 34 | _R_CHECK_TESTS_NLINES_=0 35 | _R_CHECK_USE_INSTALL_LOG_=FALSE 36 | _R_CHECK_VIGNETTES_NLINES_=0 37 | -------------------------------------------------------------------------------- /vignettes/other.bib: -------------------------------------------------------------------------------- 1 | @Manual{medicalriskpkg, 2 | title = {medicalrisk: Medical Risk and Comorbidity Tools for ICD-9-CM Data}, 3 | author = {Patrick McCormick and Thomas Joseph}, 4 | year = {2016}, 5 | note = {R package version 12}, 6 | url = {https://CRAN.R-project.org/package=medicalrisk} 7 | } 8 | 9 | @Article{comorbiditypkg, 10 | author = {Alessandro Gasparini}, 11 | title = {Comorbidity: An R Package for Computing Comorbidity Scores}, 12 | journal = {Journal of Open Source Software}, 13 | year = {2018}, 14 | volume = {3}, 15 | issue = {23}, 16 | pages = {648}, 17 | doi = {10.21105/joss.00648}, 18 | url = {https://doi.org/10.21105/joss.00648}, 19 | } 20 | 21 | @Manual{R_2018, 22 | title = {R: A Language and Environment for Statistical Computing}, 23 | author = {{R Core Team}}, 24 | organization = {R Foundation for Statistical Computing}, 25 | address = {Vienna, Austria}, 26 | year = {2018}, 27 | url = {https://www.R-project.org/}, 28 | } 29 | 30 | @MISC{eigenweb, 31 | author = {Gael Guennebaud and Benoit Jacob and others}, 32 | title = {Eigen v3, A C++ Template Library for Linear Algebra: Matrices, Vectors, Numerical Solvers, and Related Algorithms.}, 33 | version = {3}, 34 | howpublished = {http://eigen.tuxfamily.org}, 35 | year = {2010}, 36 | note = {Online; accessed 5-May-2018} 37 | } 38 | -------------------------------------------------------------------------------- /benchmarks/bench-class.R: -------------------------------------------------------------------------------- 1 | #' \dontrun{ 2 | #' # benchmark attributes vs attr for getting and setting 3 | #' rp <- "a" 4 | #' new_attr <- list(k = "b") 5 | #' times <- 1e5 6 | #' microbenchmark::microbenchmark(attr(rp, "k") <- "b", attributes(rp) <- new_attr, times = times) 7 | #' microbenchmark::microbenchmark(attr(rp, "k"), attributes(rp)[["k"]], times = times) 8 | #' microbenchmark::microbenchmark(attr(rp, "k"), attributes(rp), times = times) 9 | #' microbenchmark::microbenchmark(attr(rp, "k", exact = TRUE), attributes(rp), times = times) 10 | #' } 11 | 12 | #' 13 | #' \dontrun{ 14 | #' # benchmark subsetting to justify using .subset2 (5% faster) 15 | #' library(microbenchmark) 16 | #' j <- list(as.icd9cm("E990"), as.icd9cm("10010")) 17 | #' k <- list(rep(as.icd9cm("E990"), times = 500)) 18 | #' microbenchmark(j[[1]], .subset2(j, 1), 19 | #' k[[1]], .subset2(k, 1), 20 | #' times = 1e5) 21 | #' 22 | #' # logical list to vector 23 | #' a <- list(TRUE, TRUE) 24 | #' microbenchmark(as.logical(a), c(a, recursive = TRUE), times = 1e5) 25 | #' 26 | #' # c(..., recursive = TRUE) vs unlist 27 | #' l = list(c("100", "440", "999"), c("123", "234")) 28 | #' microbenchmark::microbenchmark(c(l, recursive = TRUE), 29 | #' c(unlist(l)), 30 | #' times = 1e5) 31 | #' stopifnot(identical(c(l, recursive = TRUE), c(unlist(l)))) 32 | #' 33 | #' } 34 | -------------------------------------------------------------------------------- /man/subset.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class.R 3 | \name{subset} 4 | \alias{subset} 5 | \alias{[.icd9} 6 | \alias{[[.icd9} 7 | \alias{[.icd10} 8 | \alias{[[.icd10} 9 | \title{extract subset(s) from ICD data} 10 | \usage{ 11 | \method{[}{icd9}(x, ...) 12 | 13 | \method{[[}{icd9}(x, ...) 14 | 15 | \method{[}{icd10}(x, ...) 16 | 17 | \method{[[}{icd10}(x, ...) 18 | } 19 | \arguments{ 20 | \item{x}{input data with list, vector, factor, and class set to an ICD type.} 21 | 22 | \item{...}{arguments passed on to other functions} 23 | } 24 | \description{ 25 | exactly the same as using \code{x[n]} or \code{x[[n]]} but preserves the ICD 26 | classes in result 27 | } 28 | \section{Methods (by class)}{ 29 | \itemize{ 30 | \item \code{icd9}: Extract ICD-9 codes 31 | 32 | \item \code{icd9}: Extract ICD-9 codes 33 | 34 | \item \code{icd10}: Extract ICD-10 codes 35 | 36 | \item \code{icd10}: Extract ICD-10 codes 37 | }} 38 | 39 | \examples{ 40 | x <- list(my_codes = as.icd9(c("V10.1", "441.1"))) 41 | x[1] 42 | x[[1]] 43 | x[[1]][2] 44 | # subsetting a list should give the underlying data structure type, 45 | # preserving the ICD class 46 | stopifnot(!inherits(x[[1]], "list")) 47 | stopifnot(!inherits(x[[1]][2], "list")) 48 | 49 | y <- as.icd10(c("A01", "B0234")) 50 | y[2] 51 | y[[2]] 52 | stopifnot(inherits(y[2], "icd10")) 53 | stopifnot(inherits(y[[2]], "icd10")) 54 | } 55 | -------------------------------------------------------------------------------- /src/comorbidMatMul.hpp: -------------------------------------------------------------------------------- 1 | // [[Rcpp::depends(RcppEigen)]] 2 | #include "icd_types.hpp" 3 | #include "local.hpp" 4 | #include "mapplus.hpp" 5 | #include "refactor.hpp" 6 | #include "relevant.hpp" 7 | 8 | using namespace Rcpp; 9 | 10 | // # nocov start 11 | #ifdef ICD_DEBUG 12 | void printCornerMap(DenseMap x); 13 | void printCornerSparse(PtsSparse x); 14 | #define PRINTCORNERMAP(x) \ 15 | Rcpp::Rcout << #x << ": "; \ 16 | printCornerMap(x); 17 | #define PRINTCORNERSP(x) \ 18 | Rcpp::Rcout << #x << ": "; \ 19 | printCornerSparse(x); 20 | #define ICD_ASSIGN(row, col) mat(row, col) = true; // bounds check 21 | #else 22 | #define PRINTCORNERMAP(x) ((void)0); 23 | #define PRINTCORNERSP(x) ((void)0); 24 | #define ICD_ASSIGN(row, col) mat.coeffRef(row, col) = true; 25 | #endif 26 | // # nocov end 27 | 28 | void buildVisitCodesSparseWide( 29 | const DataFrame &data, 30 | const std::string& id_name, 31 | const CV& code_names, 32 | const bool validate, 33 | Relevant &rh, 34 | // output 35 | PtsSparse &visMat, 36 | // output: can get this from sparse matrix at end? Needed? 37 | VecStr &visitIds); 38 | LogicalMatrix comorbidMatMulWide(const DataFrame &data, 39 | const List &map, 40 | const std::string& id_name, 41 | const CV& code_name, 42 | const bool validate = false); 43 | -------------------------------------------------------------------------------- /man/get_icd10cm_available.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/icd-cm-ver.R 3 | \name{get_icd10cm_available} 4 | \alias{get_icd10cm_available} 5 | \title{Get the ICD-10-CM versions available in this package} 6 | \usage{ 7 | get_icd10cm_available(dx = TRUE, return_year = FALSE) 8 | } 9 | \arguments{ 10 | \item{dx}{Single logical value, if \code{TRUE} the default, diagnostic codes will be retrieved and processed. If \code{FALSE}, procedure codes will be used. Note that most ICD-10 schemes around the world do not add procedure codes. The US uses them extensively, and these form the basis of the Belgian version of ICD-10.} 11 | 12 | \item{return_year}{Logical, which, if \code{TRUE}, will result in only a 13 | character vector of year (or year-like version) being returned.} 14 | } 15 | \value{ 16 | By default, the names of all the data available, for diagnostic 17 | ICD-10-CM codes, e.g. \code{icd10cm2019}. 18 | } 19 | \description{ 20 | Get the ICD-10-CM versions available in this package 21 | } 22 | \examples{ 23 | # Diagnostic codes: 24 | get_icd10cm_available() 25 | # Just get the years avaiable for ICD-10-CM procedure codes 26 | get_icd10cm_available(dx = FALSE, return_year = TRUE) 27 | # How to use the data name - most are not package data, due to severe CRAN 28 | # package size limitations, so they are retrieved and cached as needed. 29 | # The latest ICD-10-CM is included. 30 | tail(get_icd10cm_available(), n = 1) 31 | } 32 | -------------------------------------------------------------------------------- /man/short_to_decimal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/convert.R 3 | \name{short_to_decimal} 4 | \alias{short_to_decimal} 5 | \alias{short_to_decimal.default} 6 | \alias{short_to_decimal.icd9} 7 | \alias{short_to_decimal.icd10} 8 | \alias{short_to_decimal.icd10cm} 9 | \title{Convert ICD codes from short to decimal forms} 10 | \usage{ 11 | short_to_decimal(x) 12 | 13 | \method{short_to_decimal}{default}(x) 14 | 15 | \method{short_to_decimal}{icd9}(x) 16 | 17 | \method{short_to_decimal}{icd10}(x) 18 | 19 | \method{short_to_decimal}{icd10cm}(x) 20 | } 21 | \arguments{ 22 | \item{x}{ICD codes} 23 | } 24 | \description{ 25 | Convert from short to decimal forms of ICD codes. 26 | } 27 | \section{Methods (by class)}{ 28 | \itemize{ 29 | \item \code{default}: convert ICD codes of unknown type from short 30 | to decimal format 31 | 32 | \item \code{icd9}: convert ICD-9 codes from short to decimal 33 | format 34 | 35 | \item \code{icd10}: convert ICD-10 codes from short to decimal 36 | format 37 | 38 | \item \code{icd10cm}: convert ICD-10-CM code from short to decimal 39 | format 40 | }} 41 | 42 | \seealso{ 43 | Other ICD data conversion: 44 | \code{\link{comorbid_df_to_mat}()}, 45 | \code{\link{comorbid_mat_to_df}()}, 46 | \code{\link{convert}}, 47 | \code{\link{decimal_to_short}()}, 48 | \code{\link{long_to_wide}()}, 49 | \code{\link{wide_to_long}()} 50 | } 51 | \concept{ICD data conversion} 52 | \keyword{internal} 53 | \keyword{manip} 54 | -------------------------------------------------------------------------------- /src/sort.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SORT_H_ 2 | #define SORT_H_ 3 | 4 | #include "icd_types.hpp" 5 | #include "local.hpp" 6 | #include 7 | #include // std::pair 8 | #include // std::sort 9 | #include 10 | using namespace Rcpp; 11 | 12 | typedef std::pair pas_std; 13 | typedef std::pair pas_rcpp; 14 | bool icd9Compare(const Rcpp::String& a, const Rcpp::String& b); 15 | bool icd9CompareStd(std::string a, std::string b); 16 | 17 | CharacterVector icd9Sort(const Rcpp::CharacterVector &x); 18 | 19 | // or IntegerVector? 20 | std::vector icd9OrderStd(const VecStr& x); 21 | 22 | bool icd10cmCompareQuirk(const char* x, 23 | const char* y, 24 | const char *quirk, 25 | const char *beforeQuirk, 26 | const char *afterQuirk, 27 | const char *beforeBeforeQuirk, 28 | const char *afterAfterQuirk, 29 | bool& res); 30 | // inline in cpp: bool icd10cmCompare(const String& x, const String& y); 31 | CharacterVector icd10cmSort(const Rcpp::CharacterVector &x); 32 | // disable until std and rcpp implemented fully VecStr icd10cmSortStd(const std::vector &x); 33 | //Rcpp::IntegerVector icd10cmOrder(const Rcpp::CharacterVector &x); 34 | //std::vector icd10cmOrderStd(const std::vector &x); 35 | #endif /* SORT_H_ */ 36 | -------------------------------------------------------------------------------- /R/print.icd_comorbidity_map.R: -------------------------------------------------------------------------------- 1 | #' Print a comorbidity map 2 | #' 3 | #' The default is to summarize by printing the first seven comorbidities, and 4 | #' the first seven codes for each. To print the whole thing, just convert it to 5 | #' a list. 6 | #' @param x a list optionally with class \code{comorbidity_map} 7 | #' @param n_comorbidities single integer, number of comorbidities to print 8 | #' @param n_codes single integer, number of codes per comorbidity to print 9 | #' @param ... further arguments are passed to \code{print} 10 | #' @examples 11 | #' icd9_map_ahrq 12 | #' \dontrun{ 13 | #' print(icd9_map_ahrq) 14 | #' print(icd9_map_ahrq, n_comorbidities = 3, n_codes = 3) 15 | #' print(unclass(icd9_map_ahrq)) 16 | #' } 17 | #' @keywords internal 18 | #' @export 19 | print.comorbidity_map <- function(x, 20 | ..., 21 | n_comorbidities = 7, 22 | n_codes = 7) { 23 | stopifnot(is.list(x)) 24 | assert_int(n_comorbidities) 25 | assert_int(n_codes) 26 | get_n_or_len <- function(x, n) { 27 | x[seq_len(ifelse(length(x) < n, length(x), n))] 28 | } 29 | message( 30 | "Showing first ", 31 | n_comorbidities, " comorbidities, and first ", 32 | n_codes, " of each." 33 | ) 34 | print( 35 | get_n_or_len( 36 | lapply(x, get_n_or_len, n_codes), 37 | n_comorbidities 38 | ), 39 | ... 40 | ) 41 | if (length(x) > n_comorbidities) { 42 | writeLines("...") 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/testthat/test-refactor-slow.R: -------------------------------------------------------------------------------- 1 | context("refactor bigger factors") 2 | test_that("longer factors", { 3 | n <- 1e4 4 | nl <- 1e3 5 | set.seed(1441) 6 | expect_error(regexp = NA, v1 <- icd:::generate_random_short_icd9(n)) 7 | v2 <- v1 8 | v2[1] <- "INVALID" 9 | l1 <- sample(v1, size = nl) 10 | l2 <- c(NA_character_, l1) 11 | l3 <- c(l1, NA_character_) 12 | l4 <- c(l1, "XXX") 13 | expect_error(l5 <- unique(icd:::generate_random_short_icd9(n * 2)), 14 | regexp = NA 15 | ) 16 | expect_error( 17 | regexp = NA, 18 | test_cases <- expand.grid( 19 | list(v1, v2), 20 | list(l1, l2, l3, l4, l5), 21 | list(l1, l2, l3, l4, l5) 22 | ) 23 | ) 24 | for (tc in seq_along(test_cases[[1]])) { 25 | m <- test_cases[tc, 1][[1]] 26 | nl <- unique(test_cases[tc, 2][[1]]) 27 | pl <- unique(test_cases[tc, 3][[1]]) 28 | inf <- paste( 29 | "tc = ", tc, "\n", 30 | "m = c('", paste(unlist(head(m)), collapse = "', '"), "')\n", 31 | "nl = c('", paste(unlist(head(nl)), collapse = "', '"), "')\n", 32 | "np = c('", paste(unlist(head(pl)), collapse = "', '"), "')", 33 | sep = "" 34 | ) 35 | expect_identical( 36 | refactor(factor(m, levels = pl), nl), 37 | factor(factor(m, levels = pl), levels = nl), 38 | info = inf 39 | ) 40 | expect_identical( 41 | refactor(factor(m, levels = pl), nl, na.rm = FALSE, exclude_na = FALSE), 42 | factor(factor(m, levels = pl), levels = nl, exclude = NULL), 43 | info = inf 44 | ) 45 | } 46 | }) 47 | -------------------------------------------------------------------------------- /man/get_leaf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/real.R 3 | \name{get_leaf} 4 | \alias{get_leaf} 5 | \alias{get_leaf.default} 6 | \alias{get_leaf.icd9cm} 7 | \alias{get_leaf.icd9} 8 | \title{Get billable ICD codes} 9 | \usage{ 10 | get_leaf(...) 11 | 12 | \method{get_leaf}{default}(x, short_code = guess_short(x), ...) 13 | 14 | \method{get_leaf}{icd9cm}(x, short_code = guess_short(x), invert = FALSE, ...) 15 | 16 | \method{get_leaf}{icd9}(...) 17 | } 18 | \arguments{ 19 | \item{...}{arguments passed on to other functions} 20 | 21 | \item{x}{input vector of ICD codes} 22 | 23 | \item{short_code}{single logical value which determines whether the ICD-9 24 | code provided is in short (\code{TRUE}) or decimal (\code{FALSE}) form. 25 | Where reasonable, this is guessed from the input data.} 26 | 27 | \item{invert}{Single logical value. Returns the inverse of the result. E.g. 28 | if seeking valid ICD-9 codes, the invalid ones are returned.} 29 | } 30 | \description{ 31 | Get billable ICD codes, implicitly, this refers to an ICD 32 | implementation which is specialized for a country, typically for billing, 33 | e.g. ICD-9-CM in the USA. 34 | } 35 | \section{Methods (by class)}{ 36 | \itemize{ 37 | \item \code{default}: Get billable ICD codes, guessing whether ICD-9 38 | or ICD-10, and code short vs decimal type. 39 | 40 | \item \code{icd9cm}: Get billable ICD-9-CM codes 41 | 42 | \item \code{icd9}: Get billable ICD-9 codes, which is currently 43 | implemented assuming ICD-9-CM 44 | }} 45 | 46 | \keyword{internal} 47 | -------------------------------------------------------------------------------- /man/apply_hier.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/comorbid.R 3 | \name{apply_hier} 4 | \alias{apply_hier} 5 | \alias{apply_hier_elix} 6 | \alias{apply_hier_quan_elix} 7 | \alias{apply_hier_quan_deyo} 8 | \alias{apply_hier_ahrq} 9 | \title{Apply hierarchy and choose naming for each comorbidity map} 10 | \usage{ 11 | apply_hier_elix(x, abbrev_names, hierarchy = TRUE) 12 | 13 | apply_hier_quan_elix(cbd, abbrev_names, hierarchy = TRUE) 14 | 15 | apply_hier_quan_deyo(cbd, abbrev_names, hierarchy = TRUE) 16 | 17 | apply_hier_ahrq(cbd, abbrev_names, hierarchy = TRUE) 18 | } 19 | \arguments{ 20 | \item{x}{matrix or data.frame of comorbidities} 21 | 22 | \item{abbrev_names}{single logical value that defaults to \code{TRUE}, in 23 | which case the shorter human-readable names stored in e.g. 24 | \code{ahrqComorbidNamesAbbrev} are applied to the data frame column names.} 25 | 26 | \item{hierarchy}{single logical value that defaults to \code{TRUE}, in which 27 | case the hierarchy defined for the mapping is applied. E.g. in Elixhauser, 28 | you can't have uncomplicated and complicated diabetes both flagged.} 29 | } 30 | \description{ 31 | Re-used by ICD-9 and ICD-10 versions which have the same rules. 32 | } 33 | \details{ 34 | For Deyo's Charlson comorbidities, strictly speaking, there is no 35 | dropping of more e.g. uncomplicated \code{DM} if complicated \code{DM} 36 | exists, however, this is probably useful, in general and is essential when 37 | calculating the Charlson score. 38 | } 39 | \keyword{internal} 40 | \keyword{manip} 41 | -------------------------------------------------------------------------------- /man/set_icd_data_dir.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/options.R, R/resource.R 3 | \name{set_icd_data_dir} 4 | \alias{set_icd_data_dir} 5 | \alias{get_icd_data_dir} 6 | \title{Set up the data download cache, give permission to download data} 7 | \usage{ 8 | set_icd_data_dir(path = NULL) 9 | 10 | get_icd_data_dir(must_work = TRUE) 11 | } 12 | \arguments{ 13 | \item{path}{Path to a directory where cached online raw and parsed data will 14 | be cached. It will be created if it doesn't exist.} 15 | 16 | \item{must_work}{Logical, the default of \code{TRUE} will cause this to stop 17 | with an error if a usable icd data directory cannot be found or set.} 18 | } 19 | \value{ 20 | The path to the cache directory, or \code{NULL} if it could not be 21 | found. 22 | 23 | Invisibly returns the data path which was set, or NULL if not done. 24 | } 25 | \description{ 26 | This must be called by the user, as prompted on package attach with 27 | \code{library(icd)}. 28 | } 29 | \section{Functions}{ 30 | \itemize{ 31 | \item \code{get_icd_data_dir}: Get the currently active data directory, and 32 | check it exists and is writable. 33 | }} 34 | 35 | \examples{ 36 | \dontrun{ 37 | set_icd_data_dir() 38 | # or choose another directory: 39 | # set_icd_data_dir("/var/cache/icd") 40 | # If you choose a custom directory, you may wish to add this command to your .Rprofile . 41 | # then you may use: 42 | # download_all_icd_data() 43 | # or let 'icd' download data when needed. 44 | } 45 | } 46 | \seealso{ 47 | \code{\link{download_all_icd_data}} 48 | } 49 | -------------------------------------------------------------------------------- /tools/env/appveyor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #shellcheck disable=SC2034 3 | _R_CHECK_ALWAYS_LOG_VIGNETTE_OUTPUT_=TRUE 4 | _R_CHECK_AUTOCONF_=TRUE 5 | # checkbashisms not on appveyor 6 | _R_CHECK_BASHISMS_=FALSE 7 | _R_CHECK_CODE_ASSIGN_TO_GLOBALENV_=TRUE 8 | _R_CHECK_CODE_ATTACH_=TRUE 9 | _R_CHECK_CODE_USAGE_VIA_NAMESPACES_=TRUE 10 | _R_CHECK_CODETOOLS_PROFILE_="suppressLocalUnused=FALSE" 11 | #_R_CHECK_COMPILATION_FLAGS_=FALSE 12 | _R_CHECK_COMPILATION_FLAGS_KNOWN_="-Wno-unused-parameter -Wno-unused-variable -Wno-ignored-attributes -Wno-cast-function-type -Wno-unknown-warning-option -Wno-unknown-pragmas -Wno-unknown-warning -Wno-unknown-warning-option" 13 | _R_CHECK_CONNECTIONS_LEFT_OPEN_=TRUE 14 | _R_CHECK_CRAN_INCOMING_=FALSE 15 | _R_CHECK_CRAN_INCOMING_REMOTE_=FALSE 16 | #_R_CHECK_DOC_SIZES2_=FALSE 17 | #_R_CHECK_DOC_SIZES_=FALSE 18 | _R_CHECK_EXIT_ON_FIRST_ERROR_=FALSE 19 | #_R_CHECK_FORCE_SUGGESTS_=FALSE 20 | _R_CHECK_LENGTH_1_CONDITION_="verbose,abort" 21 | _R_CHECK_LENGTH_1_LOGIC2_="verbose,abort" 22 | _R_CHECK_NATIVE_ROUTINE_REGISTRATION_=TRUE 23 | _R_CHECK_NO_STOP_ON_TEST_ERROR_=FALSE 24 | _R_CHECK_NO_STOP_ON_TEST_ERROR_=TRUE 25 | _R_CHECK_ORPHANED_=FALSE 26 | _R_CHECK_PKG_SIZES_THRESHOLD_=50 27 | _R_CHECK_RD_EXAMPLES_T_AND_F_=TRUE 28 | _R_CHECK_RD_LINE_WIDTHS_=true 29 | _R_CHECK_TESTS_NLINES_=0 30 | _R_CHECK_USE_INSTALL_LOG_=TRUE 31 | _R_CHECK_VIGNETTES_NLINES_=0 32 | ICD_COVERAGE=false 33 | ICD_INTERACT=false 34 | ICD_OFFLINE=true 35 | ICD_VERBOSE=true 36 | OMP_NUM_THREADS=4 37 | R_REMOTES_NO_ERRORS_FROM_WARNINGS="true" 38 | R_REMOTES_STANDALONE="true" 39 | R_REMOTES_UPGRADE="never" 40 | -------------------------------------------------------------------------------- /R/bindings.R: -------------------------------------------------------------------------------- 1 | # Set up an environemnt to cache ICD data 2 | .icd_data_env <- new.env(parent = emptyenv()) 3 | 4 | .data_names_pkg <- c( 5 | "icd9cm2014_leaf", 6 | "icd10cm2019" # included in package data, being the latest version 7 | ) 8 | 9 | .data_names_cache <- c( 10 | # WHO 11 | "icd10who2016", 12 | "icd10who2008fr", 13 | # FR 14 | "icd10fr2019", 15 | # BE 16 | "icd10be2014", 17 | "icd10be2014_pc", 18 | "icd10be2017", 19 | "icd10be2017_pc", 20 | # ICD-9-CM leaf descriptions 21 | paste0("icd9cm", 2005:2013, "_leaf"), 22 | # RTF parsing with majors "three-digit" codes and other non-leaf nodes 23 | paste0("icd9cm", 2005:2014), 24 | # ICD-10-CM PCS 25 | paste0("icd10cm", 2014:2019, "_pc"), 26 | # ICD-10-CM DX 27 | "icd10cm2014", 28 | "icd10cm2015", 29 | "icd10cm2016", 30 | "icd10cm2017", 31 | "icd10cm2018" 32 | ) 33 | 34 | .data_names <- c( 35 | .data_names_pkg, 36 | .data_names_cache 37 | ) 38 | 39 | #' Localised synonym for \code{\link{get_icd10fr2019}}, with French column names 40 | #' @seealso \code{\link{get_icd10fr2019}} 41 | #' @export 42 | get_cim10fr2019 <- function() { 43 | if (exists("cim10fr2019", envir = .icd_data_env)) { 44 | return(get("cim10fr2019", envir = .icd_data_env)) 45 | } 46 | cim10fr2019 <- get_icd10fr2019() 47 | names(cim10fr2019) <- c( 48 | "code", 49 | "desc_courte", 50 | "desc_longue", 51 | "majeure", 52 | "trois_chiffres" 53 | ) 54 | rownames(cim10fr2019) <- NULL 55 | assign("cim10fr2019", 56 | value = cim10fr2019, 57 | envir = .icd_data_env 58 | ) 59 | cim10fr2019 60 | } 61 | -------------------------------------------------------------------------------- /tests/testthat/test-chapters.R: -------------------------------------------------------------------------------- 1 | context("chapter and sub-chapters") 2 | 3 | test_that("sub-chapters account for ICD-10-CM ordering quirks", { 4 | # C7A Malignant Neuroendocrine Tumors 5 | # C7B Secondary Neuroendocrine Tumors 6 | # D3A Benign Neuroendocrine Tumors 7 | expect_lt( 8 | which(names(icd10_sub_chapters) == "Malignant Neoplasms Of Ill-Defined, Other Secondary And Unspecified Sites"), # nolint 9 | which(names(icd10_sub_chapters) == "Malignant Neuroendocrine Tumors") 10 | ) 11 | expect_lt( 12 | which(names(icd10_sub_chapters) == "Malignant Neoplasms Of Ill-Defined, Other Secondary And Unspecified Sites"), # nolint 13 | which(names(icd10_sub_chapters) == "Secondary Neuroendocrine Tumors") 14 | ) 15 | expect_lt( 16 | which(names(icd10_sub_chapters) == "Neoplasms Of Uncertain Behavior, Polycythemia Vera And Myelodysplastic Syndromes"), # nolint 17 | which(names(icd10_sub_chapters) == "Benign Neuroendocrine Tumors") 18 | ) 19 | expect_gt( 20 | which(names(icd10_sub_chapters) == "Malignant Neoplasms Of Lymphoid, Hematopoietic And Related Tissue"), # nolint 21 | which(names(icd10_sub_chapters) == "Malignant Neuroendocrine Tumors") 22 | ) 23 | expect_gt( 24 | which(names(icd10_sub_chapters) == "Malignant Neoplasms Of Lymphoid, Hematopoietic And Related Tissue"), # nolint 25 | which(names(icd10_sub_chapters) == "Secondary Neuroendocrine Tumors") 26 | ) 27 | expect_gt( 28 | which(names(icd10_sub_chapters) == "Neoplasms Of Unspecified Behavior"), # nolint 29 | which(names(icd10_sub_chapters) == "Benign Neuroendocrine Tumors") 30 | ) 31 | }) 32 | -------------------------------------------------------------------------------- /man/icd9_map_ahrq.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mapdocs.R 3 | \docType{data} 4 | \name{icd9_map_ahrq} 5 | \alias{icd9_map_ahrq} 6 | \alias{ahrq} 7 | \alias{icd10_map_ahrq} 8 | \title{AHRQ comorbidities} 9 | \format{ 10 | list of character vectors 11 | } 12 | \source{ 13 | \url{http://www.hcup-us.ahrq.gov/toolssoftware/comorbidity/comorbidity.jsp} 14 | \url{http://www.hcup-us.ahrq.gov/toolssoftware/comorbidityicd10/comorbidity_icd10.jsp} 15 | } 16 | \description{ 17 | These mappings of comorbidities to ICD-9 and ICD-10 codes are derived 18 | directly from SAS code provided by AHRQ then translated into this R data 19 | structure. This is a revision of the Elixhauser system, notably excluding 20 | cardiac arrythmia. 21 | } 22 | \seealso{ 23 | \code{\link{comorbid_ahrq}} \code{\link{icd9_comorbid_ahrq}} 24 | \code{\link{icd10_comorbid_ahrq}} 25 | 26 | Other comorbidity maps: 27 | \code{\link{icd10_map_ahrq_pcs}}, 28 | \code{\link{icd9_map_elix}}, 29 | \code{\link{icd9_map_hcc}}, 30 | \code{\link{icd9_map_pccc}}, 31 | \code{\link{icd9_map_quan_deyo}}, 32 | \code{\link{icd9_map_quan_elix}}, 33 | \code{\link{icd9_map_single_ccs}} 34 | 35 | Other comorbidities: 36 | \code{\link{comorbid_hcc}()}, 37 | \code{\link{comorbid}()}, 38 | \code{\link{icd10_map_ahrq_pcs}}, 39 | \code{\link{icd9_map_elix}}, 40 | \code{\link{icd9_map_hcc}}, 41 | \code{\link{icd9_map_pccc}}, 42 | \code{\link{icd9_map_quan_deyo}}, 43 | \code{\link{icd9_map_quan_elix}}, 44 | \code{\link{icd9_map_single_ccs}} 45 | } 46 | \concept{comorbidities} 47 | \concept{comorbidity maps} 48 | \keyword{datasets} 49 | -------------------------------------------------------------------------------- /man/decimal_to_short.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/convert.R 3 | \name{decimal_to_short} 4 | \alias{decimal_to_short} 5 | \alias{decimal_to_short.icd9} 6 | \alias{decimal_to_short.icd10} 7 | \alias{decimal_to_short.icd10cm} 8 | \alias{decimal_to_short.default} 9 | \title{Convert Decimal format ICD codes to short format} 10 | \usage{ 11 | decimal_to_short(x) 12 | 13 | \method{decimal_to_short}{icd9}(x) 14 | 15 | \method{decimal_to_short}{icd10}(x) 16 | 17 | \method{decimal_to_short}{icd10cm}(x) 18 | 19 | \method{decimal_to_short}{default}(x) 20 | } 21 | \arguments{ 22 | \item{x}{ICD codes} 23 | } 24 | \description{ 25 | This usually just entails removing the decimal point, but also does some 26 | limited validation and tidying up. Missing leading zeroes will be added for 27 | correctness of the shortened codes. 28 | } 29 | \section{Methods (by class)}{ 30 | \itemize{ 31 | \item \code{icd9}: convert ICD-9 codes from decimal to short 32 | format 33 | 34 | \item \code{icd10}: convert ICD-10 codes from decimal to short 35 | format 36 | 37 | \item \code{icd10cm}: convert ICD-10-CM codes from decimal to short 38 | format 39 | 40 | \item \code{default}: Guess ICD version and convert decimal to 41 | short format 42 | }} 43 | 44 | \seealso{ 45 | Other ICD data conversion: 46 | \code{\link{comorbid_df_to_mat}()}, 47 | \code{\link{comorbid_mat_to_df}()}, 48 | \code{\link{convert}}, 49 | \code{\link{long_to_wide}()}, 50 | \code{\link{short_to_decimal}()}, 51 | \code{\link{wide_to_long}()} 52 | } 53 | \concept{ICD data conversion} 54 | \keyword{internal} 55 | \keyword{manip} 56 | -------------------------------------------------------------------------------- /man/get_icd9cm2014_leaf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{get_icd9cm2014_leaf} 5 | \alias{get_icd9cm2014_leaf} 6 | \alias{get_cd9cm2005_leaf} 7 | \alias{get_icd9cm2006_leaf} 8 | \alias{get_icd9cm2007_leaf} 9 | \alias{get_icd9cm2008_leaf} 10 | \alias{get_icd9cm2009_leaf} 11 | \alias{get_icd9cm2010_leaf} 12 | \alias{get_icd9cm2011_leaf} 13 | \alias{get_icd9cm2012_leaf} 14 | \alias{get_icd9cm2013_leaf} 15 | \alias{get_icd9cm2005_leaf} 16 | \title{ICD-9-CM, just billable/leaf codes} 17 | \format{ 18 | data frames with columns \code{code}, \code{short_desc}, and 19 | \code{long_desc}. 20 | } 21 | \source{ 22 | \url{http://www.cms.gov/Medicare/Coding/ICD9ProviderDiagnosticCodes/codes.html} 23 | } 24 | \description{ 25 | ICD-9-CM, just billable/leaf codes 26 | } 27 | \details{ 28 | These are derived from the final CMS published version 32 for 2014, 29 | which was unchanged since 2011. The short descriptions are in ASCII with no 30 | special characters, whereas the long descriptions contain accented 31 | characters which are stored as Unicode, \code{latin-1} or \code{cp1252}. 32 | 33 | This all done during package creation, but can be repeated by package 34 | users, including pulling the data from the web pages directly. Despite my 35 | best efforts, current locale can give different results, but this packaged 36 | data is correct, with some \code{UTF-8} encoded strings. 37 | \code{icd9cm_billable} has been removed, and is replaced by 38 | \code{icd9cm2014_leaf} now includes only the latest version (32). 39 | } 40 | \keyword{datasets} 41 | -------------------------------------------------------------------------------- /src/icd_types.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ICD_TYPES_H_ 2 | #define ICD_TYPES_H_ 3 | 4 | // also add LinkingTo element in DESCRIPTION to enable 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | typedef std::string Str; 13 | typedef std::vector VecStr; 14 | typedef std::vector VecInt; 15 | typedef std::vector VecBool; // naughty, but good compromise 16 | typedef std::vector VecChar; 17 | typedef VecChar::iterator VecCharIt; 18 | typedef VecInt::const_iterator VecIntIt; 19 | // SOMEDAY: replace int with char, but this stops Rcpp::export working 20 | typedef VecInt ComorbidOut; 21 | typedef std::vector VecVecStr; 22 | typedef std::vector VecVecInt; 23 | typedef std::vector VecVecBool; 24 | typedef VecVecInt::size_type VecVecIntSz; 25 | typedef VecInt NewOutPt; 26 | typedef std::vector NewOut; 27 | typedef VecVecInt::iterator NewOutIt; 28 | typedef std::unordered_map VisLk; 29 | typedef std::unordered_map RelMap; 30 | typedef std::pair RelPair; 31 | typedef std::unordered_set icd_set; 32 | typedef std::unordered_set US; 33 | typedef Rcpp::CharacterVector CV; 34 | 35 | typedef int SparseValue; 36 | typedef Eigen::Triplet Triplet; 37 | typedef Eigen::SparseMatrix PtsSparse; 38 | typedef Eigen::MatrixXi DenseMap; 39 | typedef std::pair VisLkPair; 40 | typedef Rcpp::sugar::IndexHash IHS; 41 | 42 | #endif /* ICD_TYPES_H_ */ 43 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^(src\/)?.*\.log$ 2 | ^.*callgrind.*\.out$ 3 | ^(vignettes\/)?\.build\.timestamp$ 4 | ^\.gdb_history$ 5 | ^\.gitconfig$ 6 | ^\.deps$ 7 | ^.*\.Rprof.*$ 8 | ^.*\.Rproj$ 9 | ^.*\.xcworkspace$ 10 | ^CONTRIBUTING\.md$ 11 | ^travis-notes\.txt$ 12 | ^Meta$ 13 | ^README-*\.png$ 14 | ^README\.Rmd$ 15 | ^README\.html$ 16 | ^\.DS_Store$ 17 | ^\.Rproj\.user$ 18 | ^\.covrignore$ 19 | ^\.git$ 20 | ^\.git.*$ 21 | ^\.lintr$ 22 | ^\.settings$ 23 | ^\.travis\..*$ 24 | ^_config\.yml$ 25 | ^aclocal\.m4$ 26 | ^appveyor\.yml$ 27 | ^autom4te\.cache$ 28 | ^bench-versus-result.*rds$ 29 | ^benchmarks 30 | ^codecov.yml$ 31 | ^codemeta\.json$ 32 | ^config\.log$ 33 | ^config\.status$ 34 | ^cran-comments\.md$ 35 | ^data-raw$ 36 | ^doc$ 37 | ^docs$ 38 | ^docs\/.*$ 39 | ^Dockerfile$ 40 | ^icd.*\.out$ 41 | ^icd\.Rcheck$ 42 | ^icd_.*tar\.gz 43 | ^inst\/doc\/benchresults\\.ods$ 44 | ^.*efficiency.*_files$ 45 | ^.*efficiency.*\.knit\..*$ 46 | ^.*efficiency.*\.utf8\..*$ 47 | ^.*country-lang-vers.*_files$ 48 | ^.*country-lang-vers.*\.knit\..*$ 49 | ^.*country-lang-vers.*\.utf8\..*$ 50 | ^lib-bench$ 51 | ^man-roxygen$ 52 | _pkgdown\.yml$ 53 | ^revdep$ 54 | ^src\/.*\.gc(da|h|no|ov)$ 55 | ^src\/.*\.o$ 56 | ^src\/.*_cache.* 57 | ^src\/.*include-dependencies(\.d)?$ 58 | ^src\/.clang-(format|tidy)$ 59 | ^src\/\.aspell$ 60 | ^src\/\.cproject$ 61 | ^src\/\.externalToolBuilders$ 62 | ^src\/\.lintr$ 63 | ^src\/icd.*\.dll$ 64 | ^src\/icd.*\.so$ 65 | ^src\/test-cpp.*$ 66 | ^src\/test-runner.*$ 67 | ^tools$ 68 | ^.*\.tex$ 69 | ^vignettes\/efficiency-prebuilt\.(Rmd|tex)$ 70 | ^vignettes\/efficiency-prebuilt_cache$ 71 | ^vignettes\/country-lang-vers-prebuilt\.(Rmd|tex)$ 72 | ^vignettes\/jss\..*$ 73 | -------------------------------------------------------------------------------- /man/combine.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/class.R 3 | \name{combine} 4 | \alias{combine} 5 | \alias{c.icd9} 6 | \alias{c.icd10} 7 | \title{Combine ICD codes} 8 | \usage{ 9 | \method{c}{icd9}(..., warn = FALSE) 10 | 11 | \method{c}{icd10}(..., warn = FALSE) 12 | } 13 | \arguments{ 14 | \item{...}{elements to combine} 15 | 16 | \item{warn}{single logical value, if \code{TRUE}, will give warnings when 17 | incompatible types are combined using \code{\link[base]{c}}} 18 | } 19 | \description{ 20 | These function implement ICD specific methods for \code{c}, i.e., 21 | combinations of lists or vectors of codes, while preserving ICD classes. Base 22 | \R \code{\link[base]{c}} just drops all user defined classes and casts down 23 | to lowest common denominator, e.g. if mixing numbers and characters. No 24 | attempt here to catch all possible combinations of feeding in mixed ICD types 25 | and other types. Let R do what it normally does, but just try to keep classes 26 | of the first item in the list. 27 | } 28 | \examples{ 29 | # Care with the following: 30 | c(as.icd9("E998"), as.icd10("A10")) 31 | # which results in both codes sharing the 'icd9' class. 32 | # ICD-10 codes 33 | (a <- as.icd10("A100SSX")) 34 | (b <- as.icd10("Z999A")) 35 | c(a, b) 36 | c(as.icd_short_diag(a), as.icd_short_diag(b)) 37 | (d <- as.icd10("A10.0SSX")) 38 | (e <- as.icd10("Z99.9A")) 39 | c(d, e) 40 | c(as.icd_decimal_diag(d), as.icd_decimal_diag(e)) 41 | # warn when mixing attribute types 42 | suppressWarnings( 43 | c(as.icd_short_diag(a), as.icd_decimal_diag(e)) 44 | ) 45 | } 46 | \seealso{ 47 | \link[=set_icd_class]{ICD data types} 48 | } 49 | -------------------------------------------------------------------------------- /man/get_valid.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/valid.R 3 | \name{get_valid} 4 | \alias{get_valid} 5 | \alias{get_valid.character} 6 | \alias{get_valid.icd9} 7 | \alias{get_valid.icd10} 8 | \alias{get_valid.icd10cm} 9 | \title{invalid subset of decimal or short_code ICD-9 codes} 10 | \usage{ 11 | get_valid(x, short_code = guess_short(x)) 12 | 13 | \method{get_valid}{character}(x, short_code = guess_short(x)) 14 | 15 | \method{get_valid}{icd9}(x, short_code = guess_short(x)) 16 | 17 | \method{get_valid}{icd10}(x, short_code = guess_short(x)) 18 | 19 | \method{get_valid}{icd10cm}(x, short_code = guess_short(x)) 20 | } 21 | \arguments{ 22 | \item{x}{input vector of ICD codes} 23 | 24 | \item{short_code}{single logical value which determines whether the ICD-9 25 | code provided is in short (\code{TRUE}) or decimal (\code{FALSE}) form. 26 | Where reasonable, this is guessed from the input data.} 27 | } 28 | \description{ 29 | Given vector of short_code or decimal ICD-9 codes, return (in the 30 | same format) those codes which are valid or invalid. Useful for generating 31 | error messages with the faulty codes if validation fails. 32 | } 33 | \section{Methods (by class)}{ 34 | \itemize{ 35 | \item \code{character}: get valid ICD codes from character vector, guessing ICD 36 | version 37 | 38 | \item \code{icd9}: Get valid ICD-9 codes 39 | 40 | \item \code{icd10}: Get valid ICD-10 codes, currently based on ICD-10-CM 41 | structure, which is a super-set of WHO ICD-10 42 | 43 | \item \code{icd10cm}: Get valid ICD-10-CM codes 44 | }} 45 | 46 | \concept{ICD-9 validation} 47 | \keyword{internal} 48 | \keyword{manip} 49 | -------------------------------------------------------------------------------- /tests/testthat/test-attr.R: -------------------------------------------------------------------------------- 1 | context("attributes") 2 | 3 | test_that("attribute is set by different mechanisms", { 4 | j <- "100" 5 | expect_false(is.short_diag(j)) 6 | expect_false(is.decimal_diag(j)) 7 | attr(j, "icd_short_diag") <- TRUE 8 | expect_true(is.short_diag(j)) 9 | expect_false(is.decimal_diag(j)) 10 | attr(j, "icd_short_diag") <- FALSE 11 | expect_false(is.short_diag(j)) 12 | expect_true(is.decimal_diag(j)) 13 | icd:::attr_short_diag(j) 14 | expect_true(is.short_diag(j)) 15 | expect_false(is.decimal_diag(j)) 16 | icd:::attr_decimal_diag(j) 17 | expect_false(is.short_diag(j)) 18 | expect_true(is.decimal_diag(j)) 19 | 20 | k <- as.decimal_diag("222") 21 | expect_false(attr(k, "icd_short_diag")) 22 | k <- as.short_diag("753") 23 | expect_true(attr(k, "icd_short_diag")) 24 | }) 25 | 26 | 27 | test_that("attribute is set by different mechanisms with icd_ functions", { 28 | j <- "100" 29 | expect_false(is.icd_short_diag(j)) 30 | expect_false(is.icd_decimal_diag(j)) 31 | attr(j, "icd_short_diag") <- TRUE 32 | expect_true(is.icd_short_diag(j)) 33 | expect_false(is.icd_decimal_diag(j)) 34 | attr(j, "icd_short_diag") <- FALSE 35 | expect_false(is.icd_short_diag(j)) 36 | expect_true(is.icd_decimal_diag(j)) 37 | icd:::attr_short_diag(j) 38 | expect_true(is.icd_short_diag(j)) 39 | expect_false(is.icd_decimal_diag(j)) 40 | icd:::attr_decimal_diag(j) 41 | expect_false(is.icd_short_diag(j)) 42 | expect_true(is.icd_decimal_diag(j)) 43 | 44 | k <- as.icd_decimal_diag("222") 45 | expect_false(attr(k, "icd_short_diag")) 46 | k <- as.icd_short_diag("753") 47 | expect_true(attr(k, "icd_short_diag")) 48 | }) 49 | -------------------------------------------------------------------------------- /tests/testthat/test-sample-data.R: -------------------------------------------------------------------------------- 1 | context("sample data") 2 | test_that("ICD-10 codes in uranium data are okay", { 3 | expect_true(all(icd::is_valid(uranium_pathology$icd10, short_code = FALSE))) 4 | skip("not sure whether there are errors in this data yet.") 5 | expect_equal( 6 | setdiff( 7 | levels(icd::decimal_to_short(uranium_pathology$icd10)), 8 | icd10cm2019$code 9 | ), 10 | character(0) 11 | ) 12 | }) 13 | 14 | test_that("sample data frames have correct class", { 15 | expect_true(icd::is.icd_long_data(uranium_pathology)) 16 | expect_true(icd::is.icd_wide_data(vermont_dx)) 17 | # should not have vector classes on the data frames themselves 18 | expect_false(any(c("icd9", "icd9cm", "icd9who") %in% class(vermont_dx))) 19 | expect_false( 20 | any(c("icd10", "icd10cm", "icd10who") %in% class(uranium_pathology)) 21 | ) 22 | }) 23 | 24 | test_that("uranium data looks okay", { 25 | # generating uranium data depends on RODBC and an access database source file, 26 | # so don't do this. 27 | expect_equal(dim(uranium_pathology), c(2376, 2)) 28 | expect_true(icd::is.decimal_diag(uranium_pathology$icd10)) 29 | expect_true(icd::is.icd10(uranium_pathology$icd10)) 30 | }) 31 | 32 | test_that("vermont data looks okay", { 33 | expect_true(icd::is.icd_wide_data(vermont_dx)) 34 | expect_equal(ncol(vermont_dx), 25) 35 | expect_gte(nrow(vermont_dx), 1000) 36 | expect_true( 37 | all( 38 | icd::is_valid( 39 | icd::wide_to_long(vermont_dx)$icd_code 40 | ) 41 | ) 42 | ) 43 | expect_true( 44 | all( 45 | icd::wide_to_long(vermont_dx)$icd_code %in% icd9cm_hierarchy$code 46 | ) 47 | ) 48 | }) 49 | -------------------------------------------------------------------------------- /tools/check-env.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # run a package check using a given set of environment variables 4 | 5 | #shellcheck disable=SC2012,SC1091 6 | #shellcheck source=find-icd-home.sh 7 | set -eu 8 | IFS=$'\n\t' 9 | function whereami() { 10 | local dir SOURCE 11 | SOURCE="${BASH_SOURCE[0]}" 12 | while [ -h "$SOURCE" ]; do 13 | dir="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 14 | SOURCE="$(readlink "$SOURCE")" 15 | [[ $SOURCE != /* ]] && SOURCE="$dir/$SOURCE" 16 | done 17 | cd -P "$( dirname "$SOURCE" )" 18 | pwd 19 | } 20 | 21 | declare ICD_HOME 22 | if [[ -z $ICD_HOME ]]; then 23 | [[ -f "$(whereami)/find-icd-home.sh" ]] && 24 | source "$(whereami)/find-icd-home.sh" 25 | 26 | if [[ $(type -t jack_icd_home) == function ]]; then { 27 | ICD_HOME="$(find_icd_home)" 28 | } else { 29 | echo "Searching for 'icd' directory in $HOME..." >&2 30 | ICD_HOME="$(shopt -s globstar; ls "$HOME/**/icd" | head -1)" 31 | } fi 32 | fi 33 | 34 | tmpd=$(mktemp -d --tmpdir icdcheckcranplus.XXXXXXXXXXX) 35 | function finish { 36 | echo -n "Finished with $tmpd. Use:" 37 | echo -n "rm -rf $tmpd" 38 | echo "to delete it." 39 | } 40 | trap finish EXIT 41 | cd "$tmpd" 42 | # build with standard release options, i.e. compacting vignettes. 43 | "${ICD_HOME}"/tools/build-full.sh 44 | # for all environment variable options see here: 45 | # https://cran.r-project.org/doc/manuals/r-release/R-ints.html#Tools 46 | set -x 47 | export "$(xargs <"${ICD_HOME}"/tools/env/plus.env)" 48 | printenv | grep CRAN 49 | declare built_pkg 50 | built_pkg="$(ls -t "$tmpd"/icd*.tar.gz | head -1)" 51 | R CMD check "$built_pkg" 52 | -------------------------------------------------------------------------------- /tools/env/jit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #shellcheck disable=SC2034 3 | # 4 | # 5 | # 6 | _R_CHECK_ALL_NON_ISO_C_=TRUE 7 | _R_CHECK_ALWAYS_LOG_VIGNETTE_OUTPUT_=TRUE 8 | _R_CHECK_CODE_ASSIGN_TO_GLOBALENV_=TRUE 9 | _R_CHECK_CODE_ATTACH_=TRUE 10 | _R_CHECK_CODE_DATA_INTO_GLOBALENV_=TRUE 11 | _R_CHECK_CODE_USAGE_VIA_NAMESPACES_=TRUE 12 | _R_CHECK_CODETOOLS_PROFILE_="suppressLocalUnused=FALSE" 13 | _R_CHECK_COMPACT_DATA_=TRUE 14 | _R_CHECK_COMPILATION_FLAGS_=FALSE 15 | _R_CHECK_CRAN_INCOMING_=FALSE 16 | _R_CHECK_CRAN_INCOMING_REMOTE_=FALSE 17 | _R_CHECK_DEPRECATED_DEFUNCT_=TRUE 18 | _R_CHECK_DOC_SIZES2_=TRUE 19 | _R_CHECK_DOT_FIRSTLIB_=TRUE 20 | _R_CHECK_EXECUTABLES_EXCLUSIONS_=FALSE 21 | _R_CHECK_EXIT_ON_FIRST_ERROR_=FALSE 22 | _R_CHECK_INSTALL_DEPENDS_=TRUE 23 | _R_CHECK_LENGTH_1_CONDITION_="verbose,abort" 24 | _R_CHECK_LENGTH_1_LOGIC2_="verbose,abort" 25 | _R_CHECK_NATIVE_ROUTINE_REGISTRATION_=TRUE 26 | _R_CHECK_NO_RECOMMENDED_=TRUE 27 | _R_CHECK_NO_STOP_ON_TEST_ERROR_=TRUE 28 | _R_CHECK_OVERWRITE_REGISTERED_S3_METHODS_=TRUE 29 | _R_CHECK_PKG_SIZES_=FALSE 30 | _R_CHECK_PRAGMAS_=TRUE 31 | _R_CHECK_R_DEPENDS_=warn 32 | _R_CHECK_R_ON_PATH_=TRUE 33 | _R_CHECK_RD_EXAMPLES_T_AND_F_=TRUE 34 | _R_CHECK_RD_LINE_WIDTHS_=TRUE 35 | _R_CHECK_REPLACING_IMPORTS_=TRUE 36 | _R_CHECK_S3_METHODS_NOT_REGISTERED_=TRUE 37 | _R_CHECK_SCREEN_DEVICE_=stop 38 | _R_CHECK_SERIALIZATION_=TRUE 39 | _R_CHECK_SUGGESTS_ONLY_=TRUE 40 | _R_CHECK_TESTS_NLINES_=0 41 | _R_CHECK_TIMINGS_=0 42 | _R_CHECK_TOPLEVEL_FILES_=TRUE 43 | _R_CHECK_USE_INSTALL_LOG_=FALSE 44 | _R_CHECK_VC_DIRS_=TRUE 45 | _R_CHECK_VIGNETTES_NLINES_=0 46 | ICD_TEST_SLOW=TRUE 47 | MAKEFLAGS=-j$(getconf _NPROCESSORS_ONLN) 48 | R_CHECK_CONSTANTS=5 49 | R_JIT_STRATEGY=3 50 | -------------------------------------------------------------------------------- /man/icd9_map_pccc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mapdocs.R 3 | \docType{data} 4 | \name{icd9_map_pccc} 5 | \alias{icd9_map_pccc} 6 | \alias{icd9_map_pccc_dx} 7 | \alias{icd9_map_pccc_pcs} 8 | \alias{icd10_map_pccc_dx} 9 | \alias{icd10_map_pccc_pcs} 10 | \title{Pediatric Complex Chronic Conditions} 11 | \description{ 12 | There are seven comorbidity maps which represent the combinations of 13 | ICD-9, ICD-10, diagnosis and procedure codes, and three also with a 14 | set of 'fixed' codes. (See reference). 15 | } 16 | \references{ 17 | Feudtner C, Feinstein JA, Zhong W, Hall M, Dai D. 18 | Pediatric complex chronic conditions classification system version 19 | 2: updated for ICD-10 and complex medical technology dependence and 20 | transplantation. BMC Pediatr. 2014 Aug8;14:199. doi: 21 | 10.1186/1471-2431-14-199. 22 | \url{https://www.ncbi.nlm.nih.gov/pubmed/25102958} 23 | } 24 | \seealso{ 25 | \url{https://feudtnerlab.research.chop.edu/ccc_version_2.php} 26 | 27 | Other comorbidity maps: 28 | \code{\link{icd10_map_ahrq_pcs}}, 29 | \code{\link{icd9_map_ahrq}}, 30 | \code{\link{icd9_map_elix}}, 31 | \code{\link{icd9_map_hcc}}, 32 | \code{\link{icd9_map_quan_deyo}}, 33 | \code{\link{icd9_map_quan_elix}}, 34 | \code{\link{icd9_map_single_ccs}} 35 | 36 | Other comorbidities: 37 | \code{\link{comorbid_hcc}()}, 38 | \code{\link{comorbid}()}, 39 | \code{\link{icd10_map_ahrq_pcs}}, 40 | \code{\link{icd9_map_ahrq}}, 41 | \code{\link{icd9_map_elix}}, 42 | \code{\link{icd9_map_hcc}}, 43 | \code{\link{icd9_map_quan_deyo}}, 44 | \code{\link{icd9_map_quan_elix}}, 45 | \code{\link{icd9_map_single_ccs}} 46 | } 47 | \concept{comorbidities} 48 | \concept{comorbidity maps} 49 | \keyword{datasets} 50 | -------------------------------------------------------------------------------- /man/is_valid_major.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/valid.R 3 | \name{is_valid.default} 4 | \alias{is_valid.default} 5 | \alias{is_valid_major} 6 | \alias{is_valid_major.default} 7 | \alias{is_valid_major.icd9} 8 | \alias{is_valid_major.icd10} 9 | \alias{icd9_is_valid_major_n} 10 | \alias{icd9_is_valid_major_v} 11 | \alias{icd9_is_valid_major_e} 12 | \title{Test whether an ICD code is major} 13 | \usage{ 14 | \method{is_valid}{default}(x, short_code = guess_short(x), ...) 15 | 16 | is_valid_major(x, whitespace_ok = TRUE) 17 | 18 | \method{is_valid_major}{default}(x, whitespace_ok = TRUE) 19 | 20 | \method{is_valid_major}{icd9}(x, whitespace_ok = TRUE) 21 | 22 | \method{is_valid_major}{icd10}(x, whitespace_ok = TRUE) 23 | 24 | icd9_is_valid_major_n(x, whitespace_ok = TRUE) 25 | 26 | icd9_is_valid_major_v(x, whitespace_ok = TRUE) 27 | 28 | icd9_is_valid_major_e(x, whitespace_ok = TRUE) 29 | } 30 | \arguments{ 31 | \item{x}{vector of ICD codes} 32 | } 33 | \value{ 34 | logical vector of same length as input, with \code{TRUE} when a code 35 | is a major (not necessarily a real one) 36 | } 37 | \description{ 38 | Codes without real or implied decimal place return \code{TRUE} 39 | } 40 | \section{Methods (by class)}{ 41 | \itemize{ 42 | \item \code{default}: Test whether an ICD code is of major type, 43 | which at present assumes ICD-9 format. Converts to character than calls 44 | \code{is_valid.character} 45 | 46 | \item \code{default}: Test whether an ICD code is of major type, 47 | either ICD-9 or ICD-10 48 | 49 | \item \code{icd9}: Test whether an ICD-9 code is of major type. 50 | 51 | \item \code{icd10}: Test whether an ICD-9 code is of major type. 52 | }} 53 | 54 | \keyword{internal} 55 | -------------------------------------------------------------------------------- /tests/testthat/test-build-maps-icd9-quan.R: -------------------------------------------------------------------------------- 1 | context("build icd9 maps") 2 | 3 | skip_slow("Skipping slow re-building of ICD-9 comorbidity maps (quan)") 4 | 5 | test_that("ahrq icd9 map recreated", { 6 | skip_no_icd_data_raw( 7 | fun = icd9_fetch_ahrq_sas, 8 | msg = "comformat2012-2013 must be downloaded with icd9_fetch_ahrq_sas()" 9 | ) 10 | # same but from source data. Should be absolutely identical. 11 | expect_identical( 12 | result <- icd9_parse_ahrq_sas(save_pkg_data = FALSE), icd9_map_ahrq 13 | ) 14 | expect_is(result, "list") 15 | expect_equal(length(result), 30) 16 | expect_equivalent(get_invalid.comorbidity_map(icd9_map_ahrq), list()) 17 | }) 18 | 19 | test_that("Quan Charlson icd9 map generated = saved", { 20 | skip_no_icd_data_raw( 21 | .dl_icd9_quan_deyo_sas, 22 | "ICD9_E_Charlson.sas must be downloaded with .dl_icd9_quan_deyo_sas" 23 | ) 24 | expect_equivalent( 25 | icd9_map_quan_deyo, icd9_parse_quan_deyo_sas(save_pkg_data = FALSE) 26 | ) 27 | expect_equivalent( 28 | get_invalid.comorbidity_map(icd9_map_quan_deyo, short_code = TRUE), 29 | list() 30 | ) 31 | }) 32 | 33 | test_that("Quan Elix icd9 map generated = saved", { 34 | expect_equivalent( 35 | icd9_map_quan_elix, 36 | icd9_generate_map_quan_elix(save_pkg_data = FALSE) 37 | ) 38 | expect_equivalent( 39 | get_invalid.comorbidity_map(icd9_map_quan_elix, short_code = TRUE), 40 | list() 41 | ) 42 | }) 43 | 44 | test_that("Elixhauser icd9 map generated = saved", { 45 | expect_equivalent( 46 | icd9_map_elix, 47 | icd9_generate_map_elix(save_pkg_data = FALSE) 48 | ) 49 | expect_equivalent( 50 | get_invalid.comorbidity_map(icd9_map_elix, short_code = TRUE), 51 | list() 52 | ) 53 | }) 54 | -------------------------------------------------------------------------------- /tests/testthat/test-parse-icd10.R: -------------------------------------------------------------------------------- 1 | context("icd10 fixed width parse") 2 | 3 | test_icd10_most_majors <- outer(LETTERS, sprintf(0:99, fmt = "%02i"), paste0) 4 | 5 | test_that("icd10 flat file details are okay", { 6 | skip_slow("this test is very slow, may download data, but is important") 7 | skip_no_icd_data_cache() 8 | # check cols at a time, so I get better error feedback: 9 | col_names <- c( 10 | "code", 11 | "billable", 12 | "short_desc", 13 | "long_desc", 14 | "three_digit", 15 | "major", 16 | "sub_chapter", 17 | "chapter" 18 | ) 19 | for (v in as.character(2014:2019)) { 20 | test_that(.get_icd10cm_name(v, TRUE), { 21 | f_info <- with_absent_action( 22 | "silent", 23 | .dl_icd10cm_year(year = v, dx = TRUE) 24 | ) 25 | if (is.null(f_info)) skip(paste0("Skipping only icd10cm", v)) 26 | res <- .parse_icd10cm_year(year = v, save_pkg_data = FALSE) 27 | expect_identical(colnames(res), col_names) 28 | expect_is(res$code, "character") 29 | expect_true(icd::is.icd10cm(res$code)) 30 | expect_is(res$code, class = "icd10") 31 | expect_is(res$billable, "logical") 32 | expect_is(res$short_desc, "character") 33 | expect_is(res$long_desc, "character") 34 | for (n in c( 35 | "three_digit", 36 | "major", 37 | "sub_chapter", 38 | "chapter" 39 | )) { 40 | expect_true(is.factor(res[[n]])) 41 | expect_identical(res, get_icd10cm_version(v)) 42 | } 43 | }) # outer test_that 44 | } # for all versions 45 | }) 46 | 47 | # github issue #116 48 | test_that("W02 is correctly parsed", { 49 | expect_equal_no_icd(icd::explain_code(icd::as.icd10cm("W02")), character(0)) 50 | }) 51 | -------------------------------------------------------------------------------- /man/is_billable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/real.R 3 | \name{is_billable} 4 | \alias{is_billable} 5 | \alias{is_billable.icd9} 6 | \alias{is_billable.icd9cm} 7 | \alias{is_billable.icd10} 8 | \alias{is_billable.icd10cm} 9 | \alias{is_billable.default} 10 | \title{Check whether a code is billable according to ICD-9-CM or ICD-10-CM} 11 | \usage{ 12 | is_billable(x, short_code = guess_short(x), ...) 13 | 14 | \method{is_billable}{icd9}(x, short_code = guess_short(x), ...) 15 | 16 | \method{is_billable}{icd9cm}(x, short_code = guess_short(x), ...) 17 | 18 | \method{is_billable}{icd10}(x, short_code = guess_short(x), ...) 19 | 20 | \method{is_billable}{icd10cm}(x, short_code = guess_short(x), ...) 21 | 22 | \method{is_billable}{default}(x, short_code = guess_short(x), ...) 23 | } 24 | \arguments{ 25 | \item{x}{input vector to test} 26 | 27 | \item{short_code}{single logical value which determines whether the ICD-9 28 | code provided is in short (\code{TRUE}) or decimal (\code{FALSE}) form. 29 | Where reasonable, this is guessed from the input data.} 30 | 31 | \item{...}{arguments passed on to other functions} 32 | } 33 | \description{ 34 | Using the equivalent \code{\link[=is_leaf]{is_leaf()}} is preferred. 35 | } 36 | \section{Methods (by class)}{ 37 | \itemize{ 38 | \item \code{icd9}: Prefer 'leaf' to 'billable' for generality. 39 | 40 | \item \code{icd9cm}: Prefer 'leaf' to 'billable' for generality. 41 | 42 | \item \code{icd10}: Prefer 'leaf' to 'billable' for generality. 43 | 44 | \item \code{icd10cm}: Prefer 'leaf' to 'billable' for generality. 45 | 46 | \item \code{default}: Prefer 'leaf' to 'billable' for generality. 47 | }} 48 | 49 | \seealso{ 50 | \code{\link[=get_leaf]{get_leaf()}} 51 | } 52 | -------------------------------------------------------------------------------- /man/vermont_dx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datadocs.R 3 | \docType{data} 4 | \name{vermont_dx} 5 | \alias{vermont_dx} 6 | \title{Hospital discharge data from Vermont} 7 | \source{ 8 | \url{http://www.healthvermont.gov/health-statistics-vital-records/health-care-systems-reporting/hospital-discharge-data} 9 | } 10 | \description{ 11 | Anonymous data from public Vermont source for 2013 12 | } 13 | \details{ 14 | Conditions of Release Release of public use data is subject to the following 15 | conditions, which the requestor agrees to upon accepting copies of the data: 16 | 17 | 1. The data may not be used in any manner that attempts to or does identify, 18 | directly or indirectly, any individual patient or physician. 19 | 20 | 2. The requestor agrees to incorporate the following, or a substantially 21 | similar, disclaimer in all reports or publications that include public use 22 | data: \dQuote{Hospital discharge data for use in this study were supplied by 23 | the Vermont Association of Hospitals and Health Systems-Network Services 24 | Organization (VAHHS-NSO) and the Vermont Department of Banking, Insurance, 25 | Securities and Health Care Administration (BISHCA). All analyses, 26 | interpretations or conclusions based on these data are solely that of [the 27 | requestor]. VAHHS-NSO and BISHCA disclaim responsibility for any such 28 | analyses, interpretations or conclusions. In addition, as the data have been 29 | edited and processed by VAHHS-NSO, BISHCA assumes no responsibility for 30 | errors in the data due to coding or processing} 31 | 32 | Format: CSV original, minimally processed into R data frame. 33 | } 34 | \author{ 35 | Vermont Division of Health Care Administration 36 | } 37 | \keyword{datasets} 38 | -------------------------------------------------------------------------------- /R/vermont_dx.R: -------------------------------------------------------------------------------- 1 | #' Generate \code{vermont_dx} data 2 | #' 3 | #' Process data from \href{healthvermont.gov}{Health Vermont} 4 | #' @template parse-template 5 | #' @examples 6 | #' \dontrun{ 7 | #' generate_vermont_dx(save_pkg_data = TRUE) 8 | #' } 9 | #' @keywords internal datagen 10 | #' @noRd 11 | .generate_vermont_dx <- function(save_pkg_data) { 12 | # This is indeed in data-raw, because not available to download anymore 13 | vermont_fp <- .get_raw_data_path("VTINP13.TXT") 14 | vermont_dx <- utils::read.csv(vermont_fp, 15 | stringsAsFactors = FALSE, 16 | strip.white = TRUE 17 | ) 18 | vermont_dx <- vermont_dx[1:1000, c(74, 4, 6, 7, 11, 13:32)] 19 | age_group <- vermont_dx$intage 20 | attr(age_group, "class") <- "factor" 21 | attr(age_group, "levels") <- c( 22 | "Under 1", "1-17", "18-24", 23 | "25-29", "30-34", "35-39", 24 | "40-44", "45-49", "50-54", 25 | "55-59", "60-64", "65-69", 26 | "70-74", "75 and over", 27 | "Unknown" 28 | ) 29 | age_group <- ordered(age_group) 30 | sex <- vermont_dx$sex 31 | attr(sex, "class") <- "factor" 32 | attr(sex, "levels") <- c("male", "female", "unknown") 33 | vermont_dx$intage <- age_group 34 | vermont_dx$sex <- sex 35 | # death = 8 (other codes are for various discharge statuses) 36 | vermont_dx$dstat <- vermont_dx$dstat == 8 37 | names(vermont_dx)[seq_len(5)] <- c( 38 | "visit_id", 39 | "age_group", 40 | "sex", 41 | "death", 42 | "DRG" 43 | ) 44 | class(vermont_dx) <- c("icd_wide_data", "data.frame") 45 | dx_cols <- paste0("DX", seq_len(20)) 46 | for (dc in dx_cols) { 47 | class(vermont_dx[[dc]]) <- c("icd9cm", "icd9", "character") 48 | attr(vermont_dx[[dc]], "icd_short_diag") <- TRUE 49 | } 50 | if (save_pkg_data) .save_in_data_dir(vermont_dx) 51 | invisible(vermont_dx) 52 | } 53 | -------------------------------------------------------------------------------- /man/icd9_map_quan_elix.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mapdocs.R 3 | \docType{data} 4 | \name{icd9_map_quan_elix} 5 | \alias{icd9_map_quan_elix} 6 | \alias{icd10_map_quan_elix} 7 | \title{Quan adaptation of Elixhauser comorbidities} 8 | \format{ 9 | list of character vectors, each named by co-morbidity 10 | } 11 | \description{ 12 | These were transcribed directly from the Quan paper referenced. 13 | } 14 | \references{ 15 | Quan, Hude, Vijaya Sundararajan, Patricia Halfon, Andrew 16 | Fong, Bernard Burnand, Jean-Christophe Luthi, L. Duncan Saunders, 17 | Cynthia A. Beck, Thomas E. Feasby, and William A. Ghali. "Coding 18 | Algorithms for Defining Comorbidities in ICD-9-CM and ICD-10 19 | Administrative Data." Medical Care 43, no. 11 (November 1, 2005): 20 | 1130-39. \url{http://www.ncbi.nlm.nih.gov/pubmed/16224307} 21 | \url{http://web.archive.org/web/20110225042437/http://www.chaps.ucalgary.ca/sas} 22 | } 23 | \seealso{ 24 | \code{\link{comorbid_quan_elix}} 25 | \code{\link{icd9_comorbid_quan_elix}} 26 | \code{\link{icd10_comorbid_quan_elix}} 27 | 28 | Other comorbidity maps: 29 | \code{\link{icd10_map_ahrq_pcs}}, 30 | \code{\link{icd9_map_ahrq}}, 31 | \code{\link{icd9_map_elix}}, 32 | \code{\link{icd9_map_hcc}}, 33 | \code{\link{icd9_map_pccc}}, 34 | \code{\link{icd9_map_quan_deyo}}, 35 | \code{\link{icd9_map_single_ccs}} 36 | 37 | Other comorbidities: 38 | \code{\link{comorbid_hcc}()}, 39 | \code{\link{comorbid}()}, 40 | \code{\link{icd10_map_ahrq_pcs}}, 41 | \code{\link{icd9_map_ahrq}}, 42 | \code{\link{icd9_map_elix}}, 43 | \code{\link{icd9_map_hcc}}, 44 | \code{\link{icd9_map_pccc}}, 45 | \code{\link{icd9_map_quan_deyo}}, 46 | \code{\link{icd9_map_single_ccs}} 47 | } 48 | \concept{comorbidities} 49 | \concept{comorbidity maps} 50 | \keyword{datasets} 51 | -------------------------------------------------------------------------------- /src/children.cpp: -------------------------------------------------------------------------------- 1 | #include "local.hpp" // for CV, VecStr 2 | #include // for advance 3 | #include 4 | using namespace Rcpp; 5 | 6 | // [[Rcpp::export(icd10_children_defined_rcpp)]] 7 | CV icd10ChildrenDefined( 8 | const CV &x, 9 | const List& lookup, 10 | const IntegerVector& nc, 11 | const bool warn = true 12 | ) { 13 | if (!lookup.containsElementNamed("code")) { 14 | stop("lookup does not have a code column"); 15 | } 16 | const CV& allCodes = lookup["code"]; 17 | if (nc.size() != allCodes.size()) { 18 | DEBUG_VEC(nc); 19 | DEBUG_VEC(allCodes); 20 | stop("nc is not the same length as allCodes!"); 21 | } 22 | const IntegerVector matchesNa = match(x, allCodes); 23 | const IntegerVector matches = matchesNa[!is_na(matchesNa)]; // R indexing 24 | VecStr kids; 25 | if (matches.length() == 0) { 26 | if (warn && x.length() > 0) 27 | warning("None of the provided ICD-10 codes matched the lookup codes"); 28 | return (CV(0)); 29 | } 30 | kids.reserve(x.length() * 10); 31 | CV tmp = lookup[0]; 32 | int last_row = tmp.length(); // zero-based index 33 | int check_row; // zero-based index 34 | int parent_len; // number of characters in original parent code 35 | TRACE("Ready to loop in icd10ChildrenDefined"); 36 | for (int i = 0; i != matches.length(); ++i) { 37 | check_row = matches[i]; // check the row after the parent 38 | parent_len = nc[matches[i] - 1]; 39 | while (check_row < last_row && nc[check_row] > parent_len) ++check_row; 40 | CV::const_iterator it = allCodes.begin(); 41 | std::advance(it, matches[i] - 1); 42 | CV::const_iterator it2 = allCodes.begin(); 43 | std::advance(it2, check_row); 44 | kids.insert(kids.end(), it, it2); 45 | } 46 | TRACE("Returning kids from icd10ChildrenDefined"); 47 | DEBUG_VEC(kids); 48 | return wrap(kids); 49 | } 50 | -------------------------------------------------------------------------------- /man/get_billable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/real.R 3 | \name{get_billable} 4 | \alias{get_billable} 5 | \alias{get_billable.icd9} 6 | \alias{get_billable.icd9cm} 7 | \alias{get_billable.icd10} 8 | \alias{get_billable.icd10cm} 9 | \alias{get_billable.default} 10 | \title{Get the subset of codes that are billable according to ICD-9-CM or ICD-10-CM} 11 | \usage{ 12 | get_billable(...) 13 | 14 | \method{get_billable}{icd9}(...) 15 | 16 | \method{get_billable}{icd9cm}(x, short_code = guess_short(x), invert = FALSE, ...) 17 | 18 | \method{get_billable}{icd10}(x, short_code = guess_short(x), invert = FALSE, ...) 19 | 20 | \method{get_billable}{icd10cm}(x, short_code = guess_short(x), invert = FALSE, ...) 21 | 22 | \method{get_billable}{default}(x, short_code = guess_short(x), ...) 23 | } 24 | \arguments{ 25 | \item{...}{arguments passed on to other functions} 26 | 27 | \item{x}{input vector of ICD codes} 28 | 29 | \item{short_code}{single logical value which determines whether the ICD-9 30 | code provided is in short (\code{TRUE}) or decimal (\code{FALSE}) form. 31 | Where reasonable, this is guessed from the input data.} 32 | 33 | \item{invert}{Single logical value. Returns the inverse of the result. E.g. 34 | if seeking valid ICD-9 codes, the invalid ones are returned.} 35 | } 36 | \description{ 37 | Using the equivalent \code{\link[=get_leaf]{get_leaf()}} is preferred. 38 | } 39 | \section{Methods (by class)}{ 40 | \itemize{ 41 | \item \code{icd9}: Prefer 'leaf' to 'billable' for generality. 42 | 43 | \item \code{icd9cm}: Prefer 'leaf' to 'billable' for generality. 44 | 45 | \item \code{icd10}: Prefer 'leaf' to 'billable' for generality. 46 | 47 | \item \code{icd10cm}: Prefer 'leaf' to 'billable' for generality. 48 | 49 | \item \code{default}: Prefer 'leaf' to 'billable' for generality. 50 | }} 51 | 52 | \seealso{ 53 | \code{\link[=is_leaf]{is_leaf()}} 54 | } 55 | -------------------------------------------------------------------------------- /tools/publish.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | 5 | #TODO: use rsync --delete? but keep robots.txt 6 | 7 | # tinytex has to be able to find its texlive root and can get confused. 8 | #PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 9 | 10 | ICD_HOME="${ICD_HOME:-"${HOME}/icd"}" 11 | GH_PAGES="${ICD_HOME//icd/icd-gh-pages}" 12 | 13 | cd "${ICD_HOME}" || { echo "cannot cd to ${ICD_HOME}" >&2; exit 1; } 14 | mkdir -p "${GH_PAGES}" 15 | (cd "${GH_PAGES}" || { echo "cannot cd to ${GH_PAGES}" >&2; exit 1; }) 16 | 17 | Rscript --vanilla -e \ 18 | 'requireNamespace("roxygen2"); 19 | requireNamespace("magick"); 20 | requireNamespace("tinytex"); 21 | requireNamespace("pkgdown"); 22 | #codemetar::write_codemeta(verbose = FALSE, use_filesize = FALSE); 23 | roxygen2::roxygenise(); pkgdown::build_site()' 24 | 25 | cd "${GH_PAGES}" 26 | 27 | rsync -r --delete --filter='P .git' --filter='P .gitignore' "${ICD_HOME}/docs/" "${GH_PAGES}" 28 | git status 29 | git add -A 30 | git commit -m "pkgdown rerun" 31 | git push origin gh-pages 32 | 33 | echo "Now sleep for github.io to rebuilt, then check links all work:" 34 | # shellcheck disable=SC2034 35 | for i in {1..60}; do 36 | echo -n '.' 37 | sleep 1 38 | done 39 | echo "" 40 | rm -rf /tmp/github.io/* 41 | mkdir -p /tmp/github.io 42 | cd /tmp/github.io || { echo "cannot cd to temp download dir" >&2; exit 1; } 43 | wget --mirror -p -o logfile.log https://jackwasey.github.io/icd/ 44 | set +eo pipefail 45 | set +x 46 | if grep -q -e '404' -e 'ERROR' logfile.log ; then 47 | grep --before-context=3 -e 404 /tmp/github.io/logfile.log | grep http > badlinks.txt 48 | sed -i '/robots.txt/d' badlinks.txt 49 | declare -i nbad 50 | nbad=$(wc -l < badlinks.txt) 51 | if (( nbad != 0 )); then 52 | echo "Found ${nbad} link(s) on github.io site that are broken" >&2 53 | fi 54 | fi 55 | echo "No broken links found." 56 | -------------------------------------------------------------------------------- /man/plot_comorbid.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_comorbid} 4 | \alias{plot_comorbid} 5 | \alias{plot_comorbid_results} 6 | \title{Basic ordered bar plot showing counts of each comorbidity} 7 | \usage{ 8 | plot_comorbid(x, comorbid_fun = icd::comorbid_ahrq, ...) 9 | 10 | plot_comorbid_results( 11 | x, 12 | sort = TRUE, 13 | fix_margin = FALSE, 14 | las = 2, 15 | cex.names = 0.75, 16 | ... 17 | ) 18 | } 19 | \arguments{ 20 | \item{x}{input patient data} 21 | 22 | \item{comorbid_fun}{Character name of function or function itself, default 23 | being \code{comorbid_ahrq}} 24 | 25 | \item{...}{Passed to \code{\link[graphics]{barplot}}} 26 | 27 | \item{sort}{Logical, default \code{TRUE} which sorts the frequencies from 28 | high to low.} 29 | 30 | \item{fix_margin}{Logical, default \code{TRUE}, which causes a 31 | \code{\link[graphics]{par}} margin to be set so the x axis labels are less 32 | likely to be truncated.} 33 | 34 | \item{las}{Integer, default is 2 which rotates the x axis labels 35 | appropriately} 36 | 37 | \item{cex.names}{Numeric, default is 0.75 which scales the text size for 38 | labels appropriately} 39 | } 40 | \description{ 41 | Basic ordered bar plot showing counts of each comorbidity 42 | } 43 | \section{Functions}{ 44 | \itemize{ 45 | \item \code{plot_comorbid_results}: Plot the results of a call to one of the 46 | comorbidity settings. 47 | }} 48 | 49 | \examples{ 50 | \dontrun{ 51 | library(icd) 52 | plot_comorbid(vermont_dx) 53 | plot_comorbid(uranium_pathology) 54 | # Or calculate the comorbidities, then plot the results 55 | cmb <- comorbid_ahrq(vermont_dx) 56 | # plot with full, not abbreviated names 57 | plot_comorbid_results(cmb, names.arg = names_ahrq) 58 | # or return with full names, and plot those: 59 | comorbid_ahrq(vermont_dx, abbrev_names = FALSE) \%>\% 60 | plot_comorbid_results() 61 | } 62 | } 63 | \keyword{hplot} 64 | -------------------------------------------------------------------------------- /tests/testthat/test-explain-who.R: -------------------------------------------------------------------------------- 1 | context("explain WHO English codes") 2 | 3 | test_that("some codes not in ICD-10-CM", { 4 | skip_missing_icd10who() 5 | for (hiv in c( 6 | "B20", "B21", "B22", "B23", "B24", 7 | "B211", 8 | "B21.1", 9 | "B219", 10 | "B21.9", 11 | "B22.7", "B238", "Z21" 12 | )) { 13 | info <- paste("HIV code: ", hiv) 14 | expect_error( 15 | regexp = NA, 16 | x <- explain_code(as.icd10who(hiv), lang = "en"), 17 | info = info 18 | ) 19 | expect_true(length(x) == 1, info = info) 20 | # workaround https://github.com/r-lib/testthat/issues/867 21 | expect_true( 22 | all( 23 | grepl("HIV", x) 24 | ), 25 | info = info 26 | ) 27 | } 28 | }) 29 | 30 | test_that("hand-picked WHO-only codes okay", { 31 | skip_missing_icd10who() 32 | expect_identical( 33 | explain_code(as.icd10who("U842")), 34 | "Resistance to antiviral drug(s)" 35 | ) 36 | }) 37 | 38 | context("explain WHO French codes") 39 | 40 | test_that("some WHO codes are not in ICD-10-CM", { 41 | skip_missing_icd10who() 42 | # https://icd.who.int/browse10/2008/fr#/Z21 43 | # https://icd.who.int/browse10/2008/fr#/B21.9 (.0 .1 .2 .3 .7 .8 .9) 44 | for (hiv in c( 45 | "B20", "B21", "B22", "B23", "B24", 46 | "B21.9", "B22.7", "B238", "Z21" 47 | )) { 48 | expect_error( 49 | regexp = NA, 50 | x <- explain_code(as.icd10who(hiv), lang = "fr"), 51 | info = paste("VIH (HIV) code: ", hiv) 52 | ) 53 | # workaround https://github.com/r-lib/testthat/issues/867 54 | expect_true(length(x) && all(grepl("VIH", x)), 55 | info = paste("VIH (HIV) code: ", hiv) 56 | ) 57 | } 58 | }) 59 | 60 | test_that("hand-picked WHO-only codes okay", { 61 | skip_missing_icd10who(ver = "2008", lang = "fr") 62 | expect_identical( 63 | explain_code(as.icd10who("F21"), lang = "fr"), 64 | "Trouble schizotypique" 65 | ) 66 | }) 67 | -------------------------------------------------------------------------------- /R/uranium_pathology.R: -------------------------------------------------------------------------------- 1 | #' Generate uranium pathology data 2 | #' 3 | #' This is downloaded from \href{https://wsu.edu}{WSU} where it appears to be 4 | #' provided in the public domain. It requires the file to be downloaded from 5 | #' source, or already stored in the raw data directory, and it appears that the 6 | #' function \code{odbcConnectAccess2007} is only available in the Windows build 7 | #' of \pkg{RODBC}. 8 | #' @template parse-template 9 | #' @source \url{https://ustur.wsu.edu/about-us/} 10 | #' @examples 11 | #' \dontrun{ 12 | #' generate_uranium_pathology(save_pkg_data = TRUE) 13 | #' } 14 | #' @keywords internal datagen 15 | #' @noRd 16 | .generate_uranium_pathology <- function(save_pkg_data = TRUE, 17 | offline = .offline()) { 18 | stopifnot(length(utils::find("odbcConnectAccess2007")) > 0) 19 | stopifnot(is.logical(save_pkg_data), length(save_pkg_data) == 1) 20 | stopifnot(is.logical(offline), length(offline) == 1) 21 | # This IS in data-raw because it is no longer available to download 22 | file_path <- .get_raw_data_path("Pathology_Office2007.accdb") 23 | # odbcConnectAccess2007 is only in the Windows version of RODBC 24 | channel <- RODBC::odbcConnectAccess2007(file_path) 25 | uranium_pathology <- RODBC::sqlFetch(channel, "qry_ICD-10") 26 | uranium_pathology <- uranium_pathology[, c("Case_No", "ICD-10_code")] 27 | names(uranium_pathology) <- c("case", "icd10") 28 | uranium_pathology <- uranium_pathology[order(uranium_pathology["case"]), ] 29 | class(uranium_pathology$icd10) <- c("icd10", "factor") 30 | attr(uranium_pathology, "icd_short_diag") <- FALSE 31 | row.names(uranium_pathology) <- seq_len(uranium_pathology) 32 | class(uranium_pathology) <- c("icd_long_data", "data.frame") 33 | if (save_pkg_data) { 34 | save(uranium_pathology, 35 | file = file.path("data", "uranium_pathology.rda") 36 | ) 37 | } 38 | invisible(uranium_pathology) 39 | } 40 | -------------------------------------------------------------------------------- /man/icd10_map_ahrq_pcs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mapdocs.R 3 | \docType{data} 4 | \name{icd10_map_ahrq_pcs} 5 | \alias{icd10_map_ahrq_pcs} 6 | \title{AHRQ ICD-10-PCS categories} 7 | \description{ 8 | The AHRQ has categorized each of the ICD-10-PCS (Procedure Codes) 9 | into one of four groups: minor diagnostic, minor therapeutic, major 10 | diagnostic or major therapeutic. This mapping can be used to get the 11 | type(s) of procedure(s) performed on a patient from a 12 | \code{data.frame} of patients and associated procedure codes in 13 | 'long' format. See the ICD-10 vignette for an example. 14 | } 15 | \details{ 16 | Currently there is no specific comorbidity function to use this data, 17 | so the generic \code{\link{comorbid}} \code{\link{icd9_comorbid}} 18 | \code{\link{icd10_comorbid}} should be used, and this data specified 19 | as the \code{map}. 20 | } 21 | \examples{ 22 | icd10_map_ahrq_pcs[["Major Diagnostic"]][1:5] 23 | icd10_map_ahrq_pcs[["Minor Therapeutic"]][1:5] 24 | } 25 | \seealso{ 26 | \code{\link{comorbid}} \code{\link{icd9_comorbid}} 27 | \code{\link{icd10_comorbid}} 28 | \url{https://www.hcup-us.ahrq.gov/toolssoftware/procedureicd10/procedure_icd10.jsp} 29 | 30 | Other comorbidity maps: 31 | \code{\link{icd9_map_ahrq}}, 32 | \code{\link{icd9_map_elix}}, 33 | \code{\link{icd9_map_hcc}}, 34 | \code{\link{icd9_map_pccc}}, 35 | \code{\link{icd9_map_quan_deyo}}, 36 | \code{\link{icd9_map_quan_elix}}, 37 | \code{\link{icd9_map_single_ccs}} 38 | 39 | Other comorbidities: 40 | \code{\link{comorbid_hcc}()}, 41 | \code{\link{comorbid}()}, 42 | \code{\link{icd9_map_ahrq}}, 43 | \code{\link{icd9_map_elix}}, 44 | \code{\link{icd9_map_hcc}}, 45 | \code{\link{icd9_map_pccc}}, 46 | \code{\link{icd9_map_quan_deyo}}, 47 | \code{\link{icd9_map_quan_elix}}, 48 | \code{\link{icd9_map_single_ccs}} 49 | } 50 | \concept{comorbidities} 51 | \concept{comorbidity maps} 52 | \keyword{datasets} 53 | -------------------------------------------------------------------------------- /tests/testthat/test-build-sysdata.R: -------------------------------------------------------------------------------- 1 | context("build sysdata") 2 | skip_slow("Skipping slow re-building of sysdata") 3 | test_that("sysdata.rda is okay", { 4 | lknames <- c( 5 | "icd9_short_n", 6 | "icd9_short_v", 7 | "icd9_short_e", 8 | "icd9_short_n_defined", 9 | "icd9_short_v_defined", 10 | "icd9_short_e_defined", 11 | "icd9_short_n_leaf", 12 | "icd9_short_v_leaf", 13 | "icd9_short_e_leaf" 14 | ) 15 | sysdat <- .generate_sysdata(save_pkg_data = FALSE) 16 | expect_equal(names(sysdat), lknames) 17 | 18 | expect_lt(length(icd9_short_n_leaf$vec), length(icd9_short_n_defined$vec)) 19 | expect_lt(length(icd9_short_v_leaf$vec), length(icd9_short_v_defined$vec)) 20 | expect_lt(length(icd9_short_e_leaf$vec), length(icd9_short_e_defined$vec)) 21 | expect_lt(length(icd9_short_n_defined$vec), length(icd9_short_n$vec)) 22 | expect_lt(length(icd9_short_v_defined$vec), length(icd9_short_v$vec)) 23 | expect_lt(length(icd9_short_e_defined$vec), length(icd9_short_e$vec)) 24 | expect_true(all(icd9_short_n_defined$env %eine% icd9_short_n$env)) 25 | expect_true(all(icd9_short_v_defined$env %eine% icd9_short_v$env)) 26 | expect_true(all(icd9_short_e_defined$env %eine% icd9_short_e$env)) 27 | 28 | expect_equal(length(icd9_short_n$env), length(icd9_short_n$vec)) 29 | expect_equal(length(icd9_short_v$env), length(icd9_short_v$vec)) 30 | expect_equal(length(icd9_short_e$env), length(icd9_short_e$vec)) 31 | expect_equal(length(icd9_short_n_defined$env), length(icd9_short_n_defined$vec)) 32 | expect_equal(length(icd9_short_v_defined$env), length(icd9_short_v_defined$vec)) 33 | expect_equal(length(icd9_short_e_defined$env), length(icd9_short_e_defined$vec)) 34 | expect_equal(length(icd9_short_n_leaf$env), length(icd9_short_n_leaf$vec)) 35 | expect_equal(length(icd9_short_v_leaf$env), length(icd9_short_v_leaf$vec)) 36 | expect_equal(length(icd9_short_e_leaf$env), length(icd9_short_e_leaf$vec)) 37 | }) 38 | -------------------------------------------------------------------------------- /R/env.R: -------------------------------------------------------------------------------- 1 | # these functions are only used in generating package data 2 | # nocov start 3 | 4 | #' create environment from vector 5 | #' 6 | #' create an environment by inserting the value \code{val} with names taken from 7 | #' \code{x} 8 | #' @noRd 9 | #' @keywords internal 10 | vec_to_env_true <- function(x, val = TRUE, 11 | env = new.env(hash = TRUE, parent = baseenv())) { 12 | lapply(x, function(y) env[[y]] <- val) 13 | env 14 | } 15 | 16 | vec_to_env_count <- function(x, 17 | env = new.env(hash = TRUE, parent = baseenv())) { 18 | for (i in seq_along(x)) { 19 | env[[x[i]]] <- i 20 | } 21 | env 22 | } 23 | 24 | #' return a new environment with names and values swapped 25 | #' 26 | #' @param env environment with values being sequence numbers used to fill 27 | #' returned vector 28 | #' @noRd 29 | #' @keywords internal 30 | env_to_vec_flip <- function(env) { 31 | out <- character(length(env)) 32 | # this assignment is very slow. Try vapply instead? 33 | lapply(ls(env), function(y) out[env[[y]]] <<- y) 34 | invisible(out) 35 | } 36 | 37 | vec_to_lookup_pair <- function(x, env = new.env( 38 | hash = TRUE, 39 | parent = baseenv() 40 | )) { 41 | for (i in seq_along(x)) { 42 | env[[x[i]]] <- i 43 | } 44 | invisible(list(env = env, vec = x)) 45 | } 46 | 47 | #' in/match equivalent for two \code{Environment} arguments 48 | #' 49 | #' \code{x} and \code{table} are identical to match. Lookup is done based on 50 | #' environment element names; contents are ignored. 51 | #' @noRd 52 | #' @keywords internal 53 | "%eine%" <- function(x, table) { 54 | vapply(ls(name = x), 55 | function(y) !is.null(table[[y]]), 56 | FUN.VALUE = logical(1L), 57 | USE.NAMES = FALSE 58 | ) 59 | } 60 | 61 | "%ine%" <- function(x, table) { 62 | !is.null(table[[x]]) 63 | } 64 | 65 | # nocov end 66 | --------------------------------------------------------------------------------