diff --git a/NAMESPACE b/NAMESPACE index 8401fd6..8cd4275 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,3 +2,4 @@ export(comorbidity) export(sample_diag) +export(score) diff --git a/R/check_output.R b/R/check_output.R index ac8fe89..21757b5 100644 --- a/R/check_output.R +++ b/R/check_output.R @@ -1,19 +1,6 @@ #' @keywords internal -.check_output <- function(x, id, score) { +.check_output <- function(x, id) { x[[id]] <- NULL - if (score == "charlson") { - x[["score"]] <- NULL - x[["index"]] <- NULL - x[["wscore"]] <- NULL - x[["windex"]] <- NULL - } else if (score == "elixhauser") { - x[["score"]] <- NULL - x[["index"]] <- NULL - x[["wscore_ahrq"]] <- NULL - x[["wscore_vw"]] <- NULL - x[["windex_ahrq"]] <- NULL - x[["windex_vw"]] <- NULL - } - # Check that all identified comorbidites are either 0 or 1 + # Check that all identified comorbidity domains are either 0 or 1 if (!all(x == 0 | x == 1)) stop("'comorbidity' ended up in an unexpected state.\nPlease report a bug with a reproducible example at https://github.com/ellessenne/comorbidity/issues\n", call. = FALSE) } diff --git a/R/codes_to_regex.R b/R/codes_to_regex.R new file mode 100644 index 0000000..c4ce46d --- /dev/null +++ b/R/codes_to_regex.R @@ -0,0 +1,6 @@ +#' @keywords internal +.codes_to_regex <- function(x) { + x <- paste(x, collapse = "|^") + x <- paste0("^", x) + return(x) +} diff --git a/R/comorbidity.R b/R/comorbidity.R index 0a574d5..083b982 100644 --- a/R/comorbidity.R +++ b/R/comorbidity.R @@ -117,13 +117,13 @@ #' ) #' #' # Charlson score based on ICD-10 diagnostic codes: -#' comorbidity(x = x, id = "id", code = "code", score = "charlson", assign0 = "none") +#' comorbidity(x = x, id = "id", code = "code", score = "charlson_icd10", assign0 = FALSE) #' #' # Elixhauser score based on ICD-10 diagnostic codes: -#' comorbidity(x = x, id = "id", code = "code", score = "elixhauser", assign0 = "none") +#' comorbidity(x = x, id = "id", code = "code", score = "elixhauser_icd10", assign0 = FALSE) #' @export -comorbidity <- function(x, id, code, score, assign0, icd = "icd10", factorise = FALSE, labelled = TRUE, tidy.codes = TRUE) { +comorbidity <- function(x, id, code, map, assign0, labelled = TRUE, tidy.codes = TRUE) { # x = x # id = "id" @@ -139,22 +139,15 @@ comorbidity <- function(x, id, code, score, assign0, icd = "icd10", factorise = arg_checks <- checkmate::makeAssertCollection() # x must be a data.frame (or a data.table) checkmate::assert_true(all(class(x) %in% c("data.frame", "data.table", "tbl", "tbl_df")), add = arg_checks) - # id, code, score, icd must be a single string value + # id, code, map must be a single string value checkmate::assert_string(id, add = arg_checks) checkmate::assert_string(code, add = arg_checks) - checkmate::assert_string(score, add = arg_checks) - checkmate::assert_string(icd, add = arg_checks) - # assign0 must be a string with possible values: 'score', 'both', 'none' - checkmate::assert_string(assign0, add = arg_checks) - checkmate::assert_true(assign0 %in% c("score", "both", "none"), add = arg_checks) - # score must be charlson, elixhauser; case insensitive - score <- tolower(score) - checkmate::assert_choice(score, choices = c("charlson", "elixhauser"), add = arg_checks) - # icd must be icd9, icd10; case insensitive - icd <- tolower(icd) - checkmate::assert_choice(icd, choices = c("icd9", "icd10"), add = arg_checks) - # factorise, labelled, tidy.codes, parallel must be a single boolean value - checkmate::assert_logical(factorise, len = 1, add = arg_checks) + checkmate::assert_string(map, add = arg_checks) + # map must be one of the supported; case insensitive + map <- tolower(map) + checkmate::assert_choice(map, choices = c("charlson_icd9", "charlson_icd10", "elixhauser_icd9", "elixhauser_icd10"), add = arg_checks) + # assign0, labelled, tidy.codes must be a single boolean value + checkmate::assert_logical(assign0, add = arg_checks) checkmate::assert_logical(labelled, len = 1, add = arg_checks) checkmate::assert_logical(tidy.codes, len = 1, add = arg_checks) # force names to be syntactically valid: @@ -179,8 +172,8 @@ comorbidity <- function(x, id, code, score, assign0, icd = "icd10", factorise = ### Tidy codes if required if (tidy.codes) x <- .tidy(x = x, code = code) - ### Extract regex for internal use - regex <- lofregex[[score]][[icd]] + ### Create regex from a list of codes + regex <- lapply(X = maps[[map]], FUN = .codes_to_regex) ### Subset only 'id' and 'code' columns if (data.table::is.data.table(x)) { @@ -217,49 +210,14 @@ comorbidity <- function(x, id, code, score, assign0, icd = "icd10", factorise = ### Turn internal DT into a DF data.table::setDF(x) - ### Compute Charlson score and Charlson index - if (score == "charlson") { - x$score <- with(x, ami + chf + pvd + cevd + dementia + copd + rheumd + pud + mld * ifelse(msld == 1 & assign0 != "none", 0, 1) + diab * ifelse(diabwc == 1 & assign0 != "none", 0, 1) + diabwc + hp + rend + canc * ifelse(metacanc == 1 & assign0 != "none", 0, 1) + msld + metacanc + aids) - x$index <- with(x, cut(score, breaks = c(0, 1, 2.5, 4.5, Inf), labels = c("0", "1-2", "3-4", ">=5"), right = FALSE)) - x$wscore <- with(x, ami + chf + pvd + cevd + dementia + copd + rheumd + pud + mld * ifelse(msld == 1 & assign0 != "none", 0, 1) + diab * ifelse(diabwc == 1 & assign0 != "none", 0, 1) + diabwc * 2 + hp * 2 + rend * 2 + canc * ifelse(metacanc == 1 & assign0 != "none", 0, 2) + msld * 3 + metacanc * 6 + aids * 6) - x$windex <- with(x, cut(wscore, breaks = c(0, 1, 2.5, 4.5, Inf), labels = c("0", "1-2", "3-4", ">=5"), right = FALSE)) - } else { - x$score <- with(x, chf + carit + valv + pcd + pvd + hypunc * ifelse(hypc == 1 & assign0 != "none", 0, 1) + hypc + para + ond + cpd + diabunc * ifelse(diabc == 1 & assign0 != "none", 0, 1) + diabc + hypothy + rf + ld + pud + aids + lymph + metacanc + solidtum * ifelse(metacanc == 1 & assign0 != "none", 0, 1) + rheumd + coag + obes + wloss + fed + blane + dane + alcohol + drug + psycho + depre) - x$index <- with(x, cut(score, breaks = c(-Inf, 0, 1, 4.5, Inf), labels = c("<0", "0", "1-4", ">=5"), right = FALSE)) - x$wscore_ahrq <- with(x, chf * 9 + carit * 0 + valv * 0 + pcd * 6 + pvd * 3 + ifelse(hypunc == 1 | hypc == 1, 1, 0) * (-1) + para * 5 + ond * 5 + cpd * 3 + diabunc * ifelse(diabc == 1 & assign0 != "none", 0, 0) + diabc * (-3) + hypothy * 0 + rf * 6 + ld * 4 + pud * 0 + aids * 0 + lymph * 6 + metacanc * 14 + solidtum * ifelse(metacanc == 1 & assign0 != "none", 0, 7) + rheumd * 0 + coag * 11 + obes * (-5) + wloss * 9 + fed * 11 + blane * (-3) + dane * (-2) + alcohol * (-1) + drug * (-7) + psycho * (-5) + depre * (-5)) - x$wscore_vw <- with(x, chf * 7 + carit * 5 + valv * (-1) + pcd * 4 + pvd * 2 + ifelse(hypunc == 1 | hypc == 1, 1, 0) * 0 + para * 7 + ond * 6 + cpd * 3 + diabunc * ifelse(diabc == 1 & assign0 != "none", 0, 0) + diabc * 0 + hypothy * 0 + rf * 5 + ld * 11 + pud * 0 + aids * 0 + lymph * 9 + metacanc * 12 + solidtum * ifelse(metacanc == 1 & assign0 != "none", 0, 4) + rheumd * 0 + coag * 3 + obes * (-4) + wloss * 6 + fed * 5 + blane * (-2) + dane * (-2) + alcohol * 0 + drug * (-7) + psycho * 0 + depre * (-3)) - x$windex_ahrq <- with(x, cut(wscore_ahrq, breaks = c(-Inf, 0, 1, 4.5, Inf), labels = c("<0", "0", "1-4", ">=5"), right = FALSE)) - x$windex_vw <- with(x, cut(wscore_vw, breaks = c(-Inf, 0, 1, 4.5, Inf), labels = c("<0", "0", "1-4", ">=5"), right = FALSE)) - } - - ### If 'assign0 = "both"', then apply hierarchy to individual comorbidity domains too - if (assign0 == "both") { - if (score == "charlson") { - # "Mild liver disease" (`mld`) and "Moderate/severe liver disease" (`msld`) - x$mld[x$msld == 1] <- 0 - # "Diabetes" (`diab`) and "Diabetes with complications" (`diabwc`) - x$diab[x$diabwc == 1] <- 0 - # "Cancer" (`canc`) and "Metastatic solid tumour" (`metacanc`) - x$canc[x$metacanc == 1] <- 0 - } else { - # "Hypertension, uncomplicated" (`hypunc`) and "Hypertension, complicated" (`hypc`) - x$hypunc[x$hypc == 1] <- 0 - # "Diabetes, uncomplicated" (`diabunc`) and "Diabetes, complicated" (`diabc`) - x$diabunc[x$diabc == 1] <- 0 - # "Solid tumour" (`solidtum`) and "Metastatic cancer" (`metacanc`) - x$solidtum[x$metacanc == 1] <- 0 - } - } - ### Check output for possible unknown-state errors - .check_output(x = x, id = id, score = score) - - ### Factorise comorbidities if requested - if (factorise) x <- .factorise(x = x, score = score) + .check_output(x = x, id = id) ### Label variables for RStudio viewer if requested - if (labelled) x <- .labelled(x = x, score = score) + if (labelled) x <- .labelled(x = x, map = map) - ### Return a tidy data.frame + ### Return it, after adding class 'comorbidity' and some attributes + class(x) <- c(class(x), "comorbidity") + attr(x = x, which = "map") <- map return(x) } diff --git a/R/factorise.R b/R/factorise.R deleted file mode 100644 index 4e363b9..0000000 --- a/R/factorise.R +++ /dev/null @@ -1,10 +0,0 @@ -#' @keywords internal -.factorise <- function(x, score) { - cols <- if (score == "charlson") { - c("ami", "chf", "pvd", "cevd", "dementia", "copd", "rheumd", "pud", "mld", "diab", "diabwc", "hp", "rend", "canc", "msld", "metacanc", "aids") - } else { - c("chf", "carit", "valv", "pcd", "pvd", "hypunc", "hypc", "para", "ond", "cpd", "diabunc", "diabc", "hypothy", "rf", "ld", "pud", "aids", "lymph", "metacanc", "solidtum", "rheumd", "coag", "obes", "wloss", "fed", "blane", "dane", "alcohol", "drug", "psycho", "depre") - } - x[cols] <- lapply(x[cols], factor, levels = 0:1, labels = c("No", "Yes")) - return(x) -} diff --git a/R/labelled.R b/R/labelled.R index 1933fc9..b6ad7c8 100644 --- a/R/labelled.R +++ b/R/labelled.R @@ -1,6 +1,6 @@ #' @keywords internal -.labelled <- function(x, score) { - attr(x, "variable.labels") <- if (score == "charlson") { +.labelled <- function(x, map) { + attr(x, "variable.labels") <- if (grepl("^charlson_", map)) { c("ID", "Myocardial infarction", "Congestive heart failure", "Peripheral vascular disease", "Cerebrovascular disease", "Dementia", "Chronic obstructive pulmonary disease", "Rheumatoid disease", "Peptic ulcer disease", "Mild liver disease", "Diabetes without chronic complications", "Diabetes with chronic complications", "Hemiplegia or paraplegia", "Renal disease", "Cancer (any malignancy)", "Moderate or severe liver disease", "Metastatic solid tumour", "AIDS/HIV", "Charlson score", "Charlson index", "Weighted Charlson score", "Weighted Charlson index") } else { c("ID", "Congestive heart failure", "Cardiac arrhythmias", "Valvular disease", "Pulmonary circulation disorders", "Peripheral vascular disorders", "Hypertension, uncomplicated", "Hypertension, complicated", "Paralysis", "Other neurological disorders", "Chronic pulmonary disease", "Diabetes, uncomplicated", "Diabetes, complicated", "Hypothyroidism", "Renal failure", "Liver disease", "Peptic ulcer disease excluding bleeding", "AIDS/HIV", "Lymphoma", "Metastatic cancer", "Solid tumour without metastasis", "Rheumatoid artritis/collaged vascular disease", "Coagulopathy", "Obesity", "Weight loss", "Fluid and electrolyte disorders", "Blood loss anaemia", "Deficiency anaemia", "Alcohol abuse", "Drug abuse", "Psychoses", "Depression", "Elixhauser score", "Elixhauser index", "Weighted Elixhauser score (AHRQ)", "Weighted Elixhauser score (val Walraven)", "Weighted Elixhauser index (AHRQ)", "Weighted Elixhauser index (van Walraven)") diff --git a/R/score.R b/R/score.R new file mode 100644 index 0000000..b5103af --- /dev/null +++ b/R/score.R @@ -0,0 +1,57 @@ +# ### Compute Charlson score and Charlson index +# if (score == "charlson") { +# x$score <- with(x, ami + chf + pvd + cevd + dementia + copd + rheumd + pud + mld * ifelse(msld == 1 & assign0 != "none", 0, 1) + diab * ifelse(diabwc == 1 & assign0 != "none", 0, 1) + diabwc + hp + rend + canc * ifelse(metacanc == 1 & assign0 != "none", 0, 1) + msld + metacanc + aids) +# x$index <- with(x, cut(score, breaks = c(0, 1, 2.5, 4.5, Inf), labels = c("0", "1-2", "3-4", ">=5"), right = FALSE)) +# x$wscore <- with(x, ami + chf + pvd + cevd + dementia + copd + rheumd + pud + mld * ifelse(msld == 1 & assign0 != "none", 0, 1) + diab * ifelse(diabwc == 1 & assign0 != "none", 0, 1) + diabwc * 2 + hp * 2 + rend * 2 + canc * ifelse(metacanc == 1 & assign0 != "none", 0, 2) + msld * 3 + metacanc * 6 + aids * 6) +# x$windex <- with(x, cut(wscore, breaks = c(0, 1, 2.5, 4.5, Inf), labels = c("0", "1-2", "3-4", ">=5"), right = FALSE)) +# } else { +# x$score <- with(x, chf + carit + valv + pcd + pvd + hypunc * ifelse(hypc == 1 & assign0 != "none", 0, 1) + hypc + para + ond + cpd + diabunc * ifelse(diabc == 1 & assign0 != "none", 0, 1) + diabc + hypothy + rf + ld + pud + aids + lymph + metacanc + solidtum * ifelse(metacanc == 1 & assign0 != "none", 0, 1) + rheumd + coag + obes + wloss + fed + blane + dane + alcohol + drug + psycho + depre) +# x$index <- with(x, cut(score, breaks = c(-Inf, 0, 1, 4.5, Inf), labels = c("<0", "0", "1-4", ">=5"), right = FALSE)) +# x$wscore_ahrq <- with(x, chf * 9 + carit * 0 + valv * 0 + pcd * 6 + pvd * 3 + ifelse(hypunc == 1 | hypc == 1, 1, 0) * (-1) + para * 5 + ond * 5 + cpd * 3 + diabunc * ifelse(diabc == 1 & assign0 != "none", 0, 0) + diabc * (-3) + hypothy * 0 + rf * 6 + ld * 4 + pud * 0 + aids * 0 + lymph * 6 + metacanc * 14 + solidtum * ifelse(metacanc == 1 & assign0 != "none", 0, 7) + rheumd * 0 + coag * 11 + obes * (-5) + wloss * 9 + fed * 11 + blane * (-3) + dane * (-2) + alcohol * (-1) + drug * (-7) + psycho * (-5) + depre * (-5)) +# x$wscore_vw <- with(x, chf * 7 + carit * 5 + valv * (-1) + pcd * 4 + pvd * 2 + ifelse(hypunc == 1 | hypc == 1, 1, 0) * 0 + para * 7 + ond * 6 + cpd * 3 + diabunc * ifelse(diabc == 1 & assign0 != "none", 0, 0) + diabc * 0 + hypothy * 0 + rf * 5 + ld * 11 + pud * 0 + aids * 0 + lymph * 9 + metacanc * 12 + solidtum * ifelse(metacanc == 1 & assign0 != "none", 0, 4) + rheumd * 0 + coag * 3 + obes * (-4) + wloss * 6 + fed * 5 + blane * (-2) + dane * (-2) + alcohol * 0 + drug * (-7) + psycho * 0 + depre * (-3)) +# x$windex_ahrq <- with(x, cut(wscore_ahrq, breaks = c(-Inf, 0, 1, 4.5, Inf), labels = c("<0", "0", "1-4", ">=5"), right = FALSE)) +# x$windex_vw <- with(x, cut(wscore_vw, breaks = c(-Inf, 0, 1, 4.5, Inf), labels = c("<0", "0", "1-4", ">=5"), right = FALSE)) +# } +# +# ### If 'assign0 = "both"', then apply hierarchy to individual comorbidity domains too +# if (assign0 == "both") { +# if (score == "charlson") { +# # "Mild liver disease" (`mld`) and "Moderate/severe liver disease" (`msld`) +# x$mld[x$msld == 1] <- 0 +# # "Diabetes" (`diab`) and "Diabetes with complications" (`diabwc`) +# x$diab[x$diabwc == 1] <- 0 +# # "Cancer" (`canc`) and "Metastatic solid tumour" (`metacanc`) +# x$canc[x$metacanc == 1] <- 0 +# } else { +# # "Hypertension, uncomplicated" (`hypunc`) and "Hypertension, complicated" (`hypc`) +# x$hypunc[x$hypc == 1] <- 0 +# # "Diabetes, uncomplicated" (`diabunc`) and "Diabetes, complicated" (`diabc`) +# x$diabunc[x$diabc == 1] <- 0 +# # "Solid tumour" (`solidtum`) and "Metastatic cancer" (`metacanc`) +# x$solidtum[x$metacanc == 1] <- 0 +# } +# } +# } +#' @export +score <- function(x, weights = NULL, assign0) { + ### First, check the function is getting a 'comorbidity' data.frame + if (!inherits(x = x, what = "comorbidity")) { + stop("This function can only be used on an object of class 'comorbidity', which you can obtain by using the 'comorbidity()' function. See ?comorbidity for more details.", call. = FALSE) + } + ### Check arguments + arg_checks <- checkmate::makeAssertCollection() + # weights must be a single string value + checkmate::assert_string(weights, add = arg_checks) + # weights must be one of the supported; case insensitive + weights <- tolower(weights) + checkmate::assert_choice(weights, choices = c("vw", "ahrq"), add = arg_checks) + # assign0 be a single boolean value + checkmate::assert_logical(assign0, add = arg_checks) + # Report if there are any errors + if (!arg_checks$isEmpty()) checkmate::reportAssertions(arg_checks) + + + + map <- attr(x = x, which = "map") + print(map) +} diff --git a/man/comorbidity.Rd b/man/comorbidity.Rd index 8d59809..81af8af 100644 --- a/man/comorbidity.Rd +++ b/man/comorbidity.Rd @@ -4,17 +4,7 @@ \alias{comorbidity} \title{Compute comorbidity scores.} \usage{ -comorbidity( - x, - id, - code, - score, - assign0, - icd = "icd10", - factorise = FALSE, - labelled = TRUE, - tidy.codes = TRUE -) +comorbidity(x, id, code, map, assign0, labelled = TRUE, tidy.codes = TRUE) } \arguments{ \item{x}{A tidy \code{data.frame} (or a \code{data.table}; \code{tibble}s are supported too) with one column containing an individual ID and a column containing all diagnostic codes. @@ -25,8 +15,6 @@ Column names must be syntactically valid names, otherwise they are forced to be \item{code}{Column of \code{x} containing diagnostic codes. Codes must be in upper case with no punctuation in order to be properly recognised.} -\item{score}{The comorbidity score to compute. Possible choices are the weighted Charlson score (\code{charlson}) and the weighted Elixhauser score (\code{elixhauser}). Values are case-insensitive.} - \item{assign0}{Apply a hierarchy of comorbidities: should a comorbidity be present in a patient with different degrees of severity, then the milder form will be assigned a value of 0. By doing this, a type of comorbidity is not counted more than once in each patient. @@ -49,13 +37,15 @@ The comorbidities that are affected by this argument are: \item "Solid tumour" (\code{solidtum}) and "Metastatic cancer" (\code{metacanc}) for the Elixhauser score. }} -\item{icd}{The version of ICD coding to use. Possible choices are ICD-9-CM (\code{icd9}) or ICD-10 (\code{icd10}). Defaults to \code{icd10}, and values are case-insensitive.} - -\item{factorise}{Return comorbidities as factors rather than numeric, where (1 = presence of comorbidity, 0 = otherwise). Defaults to \code{FALSE}.} - \item{labelled}{Attach labels to each comorbidity, compatible with the RStudio viewer via the \code{\link[utils:View]{utils::View()}} function. Defaults to \code{TRUE}.} \item{tidy.codes}{Tidy diagnostic codes? If \code{TRUE}, all codes are converted to upper case and all non-alphanumeric characters are removed using the regular expression \code{[^[:alnum:]]}. Defaults to \code{TRUE}.} + +\item{score}{The comorbidity score to compute. Possible choices are the weighted Charlson score (\code{charlson}) and the weighted Elixhauser score (\code{elixhauser}). Values are case-insensitive.} + +\item{icd}{The version of ICD coding to use. Possible choices are ICD-9-CM (\code{icd9}) or ICD-10 (\code{icd10}). Defaults to \code{icd10}, and values are case-insensitive.} + +\item{factorise}{Return comorbidities as factors rather than numeric, where (1 = presence of comorbidity, 0 = otherwise). Defaults to \code{FALSE}.} } \value{ A data frame with \code{id}, columns relative to each comorbidity domain, comorbidity score, weighted comorbidity score, and categorisations of such scores, with one row per individual. @@ -146,10 +136,10 @@ x <- data.frame( ) # Charlson score based on ICD-10 diagnostic codes: -comorbidity(x = x, id = "id", code = "code", score = "charlson", assign0 = "none") +comorbidity(x = x, id = "id", code = "code", score = "charlson_icd10", assign0 = FALSE) # Elixhauser score based on ICD-10 diagnostic codes: -comorbidity(x = x, id = "id", code = "code", score = "elixhauser", assign0 = "none") +comorbidity(x = x, id = "id", code = "code", score = "elixhauser_icd10", assign0 = FALSE) } \references{ Quan H, Sundararajan V, Halfon P, Fong A, Burnand B, Luthi JC, et al. \emph{Coding algorithms for defining comorbidities in ICD-9-CM and ICD-10 administrative data}. Medical Care 2005; 43(11):1130-1139. diff --git a/testing.R b/testing.R index c71c3bc..e9f9f68 100644 --- a/testing.R +++ b/testing.R @@ -3,8 +3,25 @@ ## Load libraries devtools::load_all() -dt <- data.frame( - `Enc ID` = 1234, - DxCode = "N390" +set.seed(1) +x <- data.frame( + id = sample(1:15, size = 200, replace = TRUE), + code = sample_diag(200), + stringsAsFactors = FALSE ) -comorbidity(dt, id = "Enc ID", code = "DxCode", icd = "icd10", score = "charlson", assign0 = F) + +# Charlson score based on ICD-10 diagnostic codes: +xx <- comorbidity(x = x, id = "id", code = "code", map = "elixhauser_icd10", assign0 = FALSE) +class(xx) +score(xx) + +asd <- as.matrix(xx[, names(maps[[attr(xx, "map")]])]) +rownames(asd) <- xx$id +vw <- matrix( + data = c(chf = 3, carit = 4, valv = 5, pcd = 2, pvd = 4, hypunc = 1, hypc = 3, para = 2, ond = 3, cpd = 5, diabunc = 2, diabc = 2, hypothy = 4, rf = 4, ld = 3, pud = 5, aids = 3, lymph = 3, metacanc = 2, solidtum = 2, rheumd = 1, coag = 2, obes = 2, wloss = 4, fed = 4, blane = 1, dane = 3, alcohol = 3, drug = 3, psycho = 2, depre = 3), + ncol = 1 +) + +asd %*% vw +# this looks good. +# how to deal with 'assign0' here though?