From d6ca45dbbfb112a108a94083625938a0a490882f Mon Sep 17 00:00:00 2001 From: rmflight Date: Wed, 10 Apr 2024 10:52:55 -0400 Subject: [PATCH] adds test_left_censorship, and all the docs to do it --- DESCRIPTION | 44 ++-- NEWS.md | 4 + R/kendalltau.R | 16 +- R/left_censorship.R | 4 +- README.Rmd | 8 +- README.html | 26 +-- README.md | 26 +-- docs/404.html | 3 +- docs/CODE_OF_CONDUCT.html | 3 +- docs/LICENSE-text.html | 3 +- docs/LICENSE.html | 5 +- docs/articles/ici-kendalltau.html | 25 ++- docs/articles/index.html | 5 +- .../articles/testing-for-left-censorship.html | 202 ++++++++++++++++++ .../figure-html/examine-missingness-1.png | Bin 0 -> 72263 bytes docs/authors.html | 11 +- docs/index.html | 27 ++- docs/news/index.html | 7 +- docs/pkgdown.yml | 5 +- docs/reference/add_uniform_noise.html | 111 ++++++++++ docs/reference/calculate_matrix_medians.html | 104 +++++++++ docs/reference/cor_matrix_2_long_df.html | 3 +- docs/reference/disable_logging.html | 3 +- docs/reference/enable_logging.html | 3 +- docs/reference/ici_kendalltau.html | 27 ++- docs/reference/ici_kendalltau_ref.html | 5 +- docs/reference/ici_kt.html | 3 +- docs/reference/index.html | 23 +- docs/reference/kt_fast.html | 7 +- docs/reference/log_memory.html | 3 +- docs/reference/log_message.html | 3 +- docs/reference/long_df_2_cor_matrix.html | 3 +- docs/reference/missing_dataset.html | 100 +++++++++ docs/reference/pairwise_completeness.html | 7 +- docs/reference/show_progress.html | 3 +- docs/reference/test_left_censorship.html | 149 +++++++++++++ docs/search.json | 2 +- docs/sitemap.xml | 15 ++ man/ici_kendalltau.Rd | 11 +- man/kt_fast.Rd | 4 +- man/pairwise_completeness.Rd | 3 + man/test_left_censorship.Rd | 6 +- vignettes/ici-kendalltau.Rmd | 4 +- vignettes/testing-for-left-censorship.Rmd | 91 ++++++++ 44 files changed, 998 insertions(+), 119 deletions(-) create mode 100644 docs/articles/testing-for-left-censorship.html create mode 100644 docs/articles/testing-for-left-censorship_files/figure-html/examine-missingness-1.png create mode 100644 docs/reference/add_uniform_noise.html create mode 100644 docs/reference/calculate_matrix_medians.html create mode 100644 docs/reference/missing_dataset.html create mode 100644 docs/reference/test_left_censorship.html create mode 100644 vignettes/testing-for-left-censorship.Rmd diff --git a/DESCRIPTION b/DESCRIPTION index 47c3d21..9c47462 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,24 +1,44 @@ Package: ICIKendallTau Title: Calculates information-content-informed Kendall-tau -Version: 1.0.5 -Date: 2024-04-08 -Authors@R: c(person(given = c("Robert", "M"), family = "Flight", role = - c("aut", "cre"), email = "rflight79@gmail.com", comment = - c(ORCID = "0000-0001-8141-7788")), person(given = c("Hunter", - "NB"), family = "Moseley", role = "aut", comment = c(ORCID = - "0000-0003-3995-5368"))) +Version: 1.1.0 +Authors@R: c( + person( + given = c("Robert", "M"), + family = "Flight", + role = c("aut", "cre"), + email = "rflight79@gmail.com", + comment = c(ORCID = "0000-0001-8141-7788")), + person( + given = c("Hunter", "NB"), + family = "Moseley", + role = "aut", + comment = c(ORCID = "0000-0003-3995-5368"))) Description: Provides functions for calculating information-content-informed Kendall-tau. This version of Kendall-tau allows for the inclusion of missing values. VignetteBuilder: knitr +LazyData: true License: MIT + file LICENSE Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.3.1 LinkingTo: Rcpp -Imports: Rcpp, purrr, utils, stringr -Suggests: furrr, future, testthat (>= 3.0.0), microbenchmark, - rmarkdown, knitr, dplyr, logger -URL: https://moseleybioinformaticslab.github.io/ICIKendallTau - https://github.com/moseleybioinformaticslab/ICIKendallTau +Imports: Rcpp, + purrr, + utils, + stringr, + stats +Suggests: furrr, + future, + testthat (>= 3.0.0), + microbenchmark, + rmarkdown, + knitr, + dplyr, + logger, + withr, + naniar +URL: https://moseleybioinformaticslab.github.io/ICIKendallTau/ + https://github.com/moseleybioinformaticslab/ICIKendallTau/ +BugReports: https://github.com/moseleybioinformaticslab/ICIKendallTau/issues Config/testthat/edition: 3 diff --git a/NEWS.md b/NEWS.md index 6881600..b3206b8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# ICIKendallTau 1.1.0 + +- adds the function `test_left_censorship` to verify if `ici_kendalltau` is appropriate to use on the data or not. + # ICIKendallTau 1.0.0 - Calculates correlation between columns of the matrix, **not** the rows. diff --git a/R/kendalltau.R b/R/kendalltau.R index 1e7ab6d..fdb843c 100644 --- a/R/kendalltau.R +++ b/R/kendalltau.R @@ -12,11 +12,9 @@ #' @param check_timing logical to determine should we try to estimate run time for full dataset? (default is FALSE) #' @param return_matrix logical, should the data.frame or matrix result be returned? #' -#' @seealso [vignette("ici-kendalltau", package = "ICIKendallTau")] [test_left_censorship()] +#' @seealso [test_left_censorship()] [pairwise_completeness()] [kt_fast()] #' -#' @details For more details, see the ICI-Kendall-tau vignette -#' -#' \code{browseVignettes("ICIKendallTau")} +#' @details For more details, see the vignette `vignette("ici-kendalltau", package = "ICIKendallTau"))` #' #' The default for \code{global_na} includes what values in the data to replace with NA for the Kendall-tau calculation. By default these are \code{global_na = c(NA, Inf, 0)}. If you want to replace something other than 0, for example, you might use \code{global_na = c(NA, Inf, -2)}, and all values of -2 will be replaced instead of 0. #' @@ -30,6 +28,10 @@ #' * taumax: the theoretical maximum kendall-tau value possible #' #' Eventually, we plan to provide two more parameters for replacing values, \code{feature_na} for feature specific NA values and \code{sample_na} for sample specific NA values. +#' +#' If you want to know if the missing values in your data are possibly due to +#' left-censorship, we recommend testing that hypothesis with [test_left_censorship()] +#' first. #' #' @return list with cor, raw, pval, taumax #' @@ -315,8 +317,8 @@ ici_kendalltau = function(data_matrix, #' @param use an optional character string giving a method for computing correlations in the presence of missing values. This must be (an abbreviation of) one of the strings "everything", "all.obs", "complete.obs", or "pairwise.complete.obs". #' @param return_matrix Should the matrices of values be returned, or a long data.frame #' -#' @details Although the interface is *mostly* identical to the built-in `stats::cor` method, -#' there are some differences. +#' @details Although the interface is *mostly* identical to the built-in +#' [stats::cor()] method, there are some differences. #' #' * if providing both `x` and `y`, it is assumed they are both #' single vectors. @@ -535,6 +537,8 @@ kt_fast = function(x, y = NULL, use = "everything", return_matrix = TRUE) #' @param include_only is there certain comparisons to do? #' @param return_matrix should the matrix or data.frame be returned? #' +#' @seealso [ici_kendalltau()] +#' #' @export #' #' @return matrix of degree of completeness diff --git a/R/left_censorship.R b/R/left_censorship.R index 040cd51..039b102 100644 --- a/R/left_censorship.R +++ b/R/left_censorship.R @@ -17,7 +17,9 @@ #' instances (minus missing values) as the number of trials, and the number of #' of features below the sample medians as the number of successes. #' -#' @seealso [vignette("testing-for-left-censorship", package = "ICIKendallTau")] +#' There is a bit more detail in the vignette: `vignette("testing-for-left-censorship", package = "ICIKendallTau")` +#' +#' @seealso [ici_kendalltau()] #' #' @examples #' # this example has 80% missing due to left-censorship diff --git a/README.Rmd b/README.Rmd index 14da6aa..40e33d5 100644 --- a/README.Rmd +++ b/README.Rmd @@ -21,7 +21,7 @@ knitr::opts_chunk$set( [![ICIKendallTau status badge](https://moseleybioinformaticslab.r-universe.dev/badges/ICIKendallTau)](https://moseleybioinformaticslab.r-universe.dev) -You can see the pkgdown site [here](https://moseleybioinformaticslab.github.io/ICIKendallTau). +You can see the pkgdown site [here](https://moseleybioinformaticslab.github.io/ICIKendallTau/). ## Installation @@ -49,7 +49,7 @@ install.packages("ICIKendallTau") * In these cases, NA is informative. * Therefore, in **most** analytical measurements (gene expression, proteomics, metabolomics), missing measurements should be included, and contribute to the correlation. -If you want to read more on **how** we solve this problem, see the package vignette. +If you want to read more on **how** we solve this problem, see the package [vignette](https://moseleybioinformaticslab.github.io/ICIKendallTau/articles/ici-kendalltau.html). ## Package Functions @@ -65,6 +65,8 @@ The functions that implement this include: * `plan(multiprocess)` * Otherwise will only use a single core. +We've also included a function for testing if the missingness in your data comes from left-censorship, `test_left_censorship`. We walk through creating example data and testing it in the vignette [Testing for Left Censorship](https://moseleybioinformaticslab.github.io/ICIKendallTau/articles/testing-for-left-censorship). + ## Examples The most common case is a large matrix of independent samples (columns) and measured features in each of the samples (i.e. gene expression). @@ -158,7 +160,7 @@ r_3 = ici_kendalltau(matrix_2) In the case of hundreds of thousands of comparisons to be done, the result matrices can become very, very large, and require lots of memory for storage. They are also inefficient, as both the lower and upper triangular components are stored. An alternative storage format is as a `data.frame`, where there is a single row for each comparison performed. -This is actually how the results are stored internally, and then they are converted to a matrix form if requested (the default).s +This is actually how the results are stored internally, and then they are converted to a matrix form if requested (the default). To keep the `data.frame` output, add the argument `return_matrix=FALSE` to the call of `ici_kendalltau`. ```{r} diff --git a/README.html b/README.html index c3315be..b6d099e 100644 --- a/README.html +++ b/README.html @@ -606,10 +606,10 @@

ICIKendallTau

-

ICIKendallTau status badge

+

ICIKendallTau status badge

-

You can see the pkgdown site here.

+

You can see the pkgdown site here.

Installation

You can install the current version of ICIKendallTau via GitHub:

remotes::install_github("MoseleyBioinformaticsLab/ICIKendallTau")
@@ -639,7 +639,7 @@

Problem

If you want to read more on how we solve this -problem, see the package vignette.

+problem, see the package vignette.

Package Functions

The functions that implement this include:

+

We’ve also included a function for testing if the missingness in your +data comes from left-censorship, test_left_censorship. We +walk through creating example data and testing it in the vignette Testing +for Left Censorship.

Examples

The most common case is a large matrix of independent samples (columns) and measured features in each of the samples (i.e. gene @@ -721,14 +725,10 @@

Is It Fast?

times = 5 ) #> Unit: microseconds -#> expr min lq mean median uq max -#> cor(x, y, method = "kendall") 11506.697 11670.094 12169.6628 12006.418 12482.883 13182.222 -#> ici_kt(x, y, "global") 243.866 250.125 294.6542 275.104 320.058 384.118 -#> ici_kt(x2, y2, "global") 13467.011 13739.312 14658.5050 14945.446 14987.140 16153.616 -#> neval -#> 5 -#> 5 -#> 5 +#> expr min lq mean median uq max neval +#> cor(x, y, method = "kendall") 11685.244 12730.878 12860.9060 13071.630 13406.514 13410.264 5 +#> ici_kt(x, y, "global") 263.306 268.503 332.1288 274.858 283.589 570.388 5 +#> ici_kt(x2, y2, "global") 14110.743 14322.836 15782.6490 16053.907 16595.979 17829.780 5

In the case of 40,000 features, the average time on a modern CPU is 14 milliseconds.

Of course, if you want to use it to calculate Kendall-tau-b without @@ -757,7 +757,7 @@

Many Many Comparisons

triangular components are stored. An alternative storage format is as a data.frame, where there is a single row for each comparison performed. This is actually how the results are stored internally, and -then they are converted to a matrix form if requested (the default).s To +then they are converted to a matrix form if requested (the default). To keep the data.frame output, add the argument return_matrix=FALSE to the call of ici_kendalltau.

@@ -770,7 +770,7 @@

Many Many Comparisons

#> 3 s4 s4 0 1.0000000 0 1.000000 1.0000000 #> #> $run_time -#> [1] 0.01606894 +#> [1] 0.01747489

Code of Conduct

Please note that the ICIKendallTau project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide diff --git a/README.md b/README.md index 7435e20..c50e03f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ badge](https://moseleybioinformaticslab.r-universe.dev/badges/ICIKendallTau)](ht You can see the pkgdown site -[here](https://moseleybioinformaticslab.github.io/ICIKendallTau). +[here](https://moseleybioinformaticslab.github.io/ICIKendallTau/). ## Installation @@ -47,7 +47,8 @@ install.packages("ICIKendallTau") and contribute to the correlation. If you want to read more on **how** we solve this problem, see the -package vignette. +package +[vignette](https://moseleybioinformaticslab.github.io/ICIKendallTau/articles/ici-kendalltau.html). ## Package Functions @@ -66,6 +67,11 @@ The functions that implement this include: - `plan(multiprocess)` - Otherwise will only use a single core. +We’ve also included a function for testing if the missingness in your +data comes from left-censorship, `test_left_censorship`. We walk through +creating example data and testing it in the vignette [Testing for Left +Censorship](https://moseleybioinformaticslab.github.io/ICIKendallTau/articles/testing-for-left-censorship). + ## Examples The most common case is a large matrix of independent samples (columns) @@ -136,14 +142,10 @@ microbenchmark( times = 5 ) #> Unit: microseconds -#> expr min lq mean median uq max -#> cor(x, y, method = "kendall") 11506.697 11670.094 12169.6628 12006.418 12482.883 13182.222 -#> ici_kt(x, y, "global") 243.866 250.125 294.6542 275.104 320.058 384.118 -#> ici_kt(x2, y2, "global") 13467.011 13739.312 14658.5050 14945.446 14987.140 16153.616 -#> neval -#> 5 -#> 5 -#> 5 +#> expr min lq mean median uq max neval +#> cor(x, y, method = "kendall") 11685.244 12730.878 12860.9060 13071.630 13406.514 13410.264 5 +#> ici_kt(x, y, "global") 263.306 268.503 332.1288 274.858 283.589 570.388 5 +#> ici_kt(x2, y2, "global") 14110.743 14322.836 15782.6490 16053.907 16595.979 17829.780 5 ``` In the case of 40,000 features, the average time on a modern CPU is 14 @@ -188,7 +190,7 @@ for storage. They are also inefficient, as both the lower and upper triangular components are stored. An alternative storage format is as a `data.frame`, where there is a single row for each comparison performed. This is actually how the results are stored internally, and then they -are converted to a matrix form if requested (the default).s To keep the +are converted to a matrix form if requested (the default). To keep the `data.frame` output, add the argument `return_matrix=FALSE` to the call of `ici_kendalltau`. @@ -202,7 +204,7 @@ r_4 #> 3 s4 s4 0 1.0000000 0 1.000000 1.0000000 #> #> $run_time -#> [1] 0.01606894 +#> [1] 0.01747489 ``` ## Code of Conduct diff --git a/docs/404.html b/docs/404.html index 30f4568..fc211cc 100644 --- a/docs/404.html +++ b/docs/404.html @@ -24,7 +24,7 @@ ICIKendallTau - 1.0.2 + 1.1.0 + +

+ + + +
+ + + + +
+
+ + + + +
+

Why? +

+

{ICIKendallTau} has a very specific assumption, that the missing +values are largely due to being below the limit of +detection, or the result of left-censorship. Therefore, it should only +be used if the missing values are from left-censorship. +Ideally, it would be nice to have a way to test for it.

+
+
+

Strategy +

+

To test this, we do the following (implemented in +test_left_censorship). For any feature that is missing in +one or more samples in a class of samples, we check if the non-missing +entries are below their sample’s median values. We count all of the +entries below sample medians as successes, and the total number of +possible entries as the number of trials in a binomial test, aggregating +across all features that had a missing value. We can then perform a +one-tailed binomial test with the expectation that the successes are +greater than 0.5.

+
+
+

Fake Data +

+

To start, we need to make some fake data that we can evaluate the +test on. We will make a smallish dataset, with 1000 features across 20 +samples, and we will have 80% of the missing values be due to being +left-censored.

+

We sort the initial data so we know where we can easily put +missingness due to left-censoring. We also use a log-normal distribution +initially, just because.

+
+set.seed(1234)
+n_feature = 1000
+n_sample = 20
+n_miss = 100
+n_low = 80
+test_dataset = rlnorm(n_feature, 10, 1)
+test_dataset = sort(test_dataset)
+  
+noisy_dataset = add_uniform_noise(log(test_dataset), n_sample, 0.1)
+sample_medians = calculate_matrix_medians(noisy_dataset)
+
+
+

Add Missingness +

+

Now we can sample some low and high indices to add our missingness, +as well as some samples to add them to.

+
+low_indices = sample(seq_len(300), n_low)
+hi_indices = sample(seq(800, 1000), n_miss - n_low)
+  
+all_indices = c(low_indices, hi_indices)
+sample_indices = sample(n_sample, n_miss, replace = TRUE)
+
+missing_dataset = noisy_dataset
+for (i_loc in seq_along(all_indices)) {
+  missing_dataset[all_indices[i_loc], sample_indices[i_loc]] = NA
+}
+

We can actually visualize the missingness using the +naniar package.

+
+naniar::vis_miss(as.data.frame(missing_dataset))
+

+
+
+

Test +

+

Now we can actually test the missingness entries.

+
+missing_test = test_left_censorship(missing_dataset)
+missing_test
+#> $values
+#>   trials success class
+#> 1   1900    1520     A
+#> 
+#> $binomial_test
+#> 
+#>  Exact binomial test
+#> 
+#> data:  total_success and total_trials
+#> number of successes = 1520, number of trials = 1900, p-value < 2.2e-16
+#> alternative hypothesis: true probability of success is greater than 0.5
+#> 95 percent confidence interval:
+#>  0.7843033 1.0000000
+#> sample estimates:
+#> probability of success 
+#>                    0.8
+
+
+
+ + + +
+ + + +
+
+ + + + + + + diff --git a/docs/articles/testing-for-left-censorship_files/figure-html/examine-missingness-1.png b/docs/articles/testing-for-left-censorship_files/figure-html/examine-missingness-1.png new file mode 100644 index 0000000000000000000000000000000000000000..1c7f93a14b91abd49f7e13393c44711590ec385a GIT binary patch literal 72263 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 A5dZ)H literal 0 HcmV?d00001 diff --git a/docs/authors.html b/docs/authors.html index 866bf5e..7905639 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -10,7 +10,7 @@ ICIKendallTau - 1.0.2 + 1.1.0 + +

+ + + +
+
+
+ +
+

Adds uniform noise to values, generating replicates with noise added to +the original.

+
+ +
+

Usage

+
add_uniform_noise(value, n_rep, sd, use_zero = FALSE)
+
+ +
+

Arguments

+
value
+

a single or vector of numeric values

+ + +
n_rep
+

the number of replicates to make (numeric). Default is 1.

+ + +
sd
+

the standard deviation of the data

+ + +
use_zero
+

logical, should returned values be around zero or not?

+ +
+
+

Value

+ + +

numeric matrix

+
+ +
+ + +
+ + + +
+ + + + + + + diff --git a/docs/reference/calculate_matrix_medians.html b/docs/reference/calculate_matrix_medians.html new file mode 100644 index 0000000..1ab6074 --- /dev/null +++ b/docs/reference/calculate_matrix_medians.html @@ -0,0 +1,104 @@ + +Calculate matrix medians — calculate_matrix_medians • ICIKendallTau + Skip to contents + + +
+
+
+ +
+

Given a matrix of data, calculates the median value in each column or row.

+
+ +
+

Usage

+
calculate_matrix_medians(in_matrix, use = "col", ...)
+
+ +
+

Arguments

+
in_matrix
+

numeric matrix of values

+ + +
use
+

character of "col" or "row" defining columns or rows

+ + +
...
+

extra parameters to the median function

+ +
+
+

Value

+ + +

numeric

+
+ +
+ + +
+ + + +
+ + + + + + + diff --git a/docs/reference/cor_matrix_2_long_df.html b/docs/reference/cor_matrix_2_long_df.html index 3e14548..49d70bd 100644 --- a/docs/reference/cor_matrix_2_long_df.html +++ b/docs/reference/cor_matrix_2_long_df.html @@ -10,7 +10,7 @@ ICIKendallTau - 1.0.2 + 1.1.0 + + + + + +
+
+
+ +
+

An example dataset that has missingness from left-censorship

+
+ +
+

Usage

+
missing_dataset
+
+ +
+

Format

+ +
+

missing_dataset

+ + +

A matrix with 1000 rows and 20 columns, where rows are features and +columns are samples.

+
+ +
+
+

Source

+

Robert M Flight

+
+ +
+ + +
+ + + +
+ + + + + + + diff --git a/docs/reference/pairwise_completeness.html b/docs/reference/pairwise_completeness.html index 242aa26..71b9ff4 100644 --- a/docs/reference/pairwise_completeness.html +++ b/docs/reference/pairwise_completeness.html @@ -12,7 +12,7 @@ ICIKendallTau - 1.0.2 + 1.1.0 + + + + + +
+
+
+ +
+

Does a binomial test to check if the most likely cause of missing values +is due to values being below the limit of detection, or coming from a +left-censored distribution.

+
+ +
+

Usage

+
test_left_censorship(in_data, sample_classes = NULL, global_na = c(NA, Inf, 0))
+
+ +
+

Arguments

+
in_data
+

matrix or data.frame of numeric data

+ + +
sample_classes
+

which samples are in which class

+ + +
global_na
+

what represents zero or missing?

+ +
+
+

Value

+ + +

data.frame of trials / successes, and binom.test result

+
+
+

Details

+

For each feature that is missing in a group of samples, we save as a possibility +to test. For each sample, we calculate the median value with any missing values +removed. Each feature that had a missing value, we test whether the remaining +non-missing values are below the sample median for those samples where the +feature is non-missing. A binomial test considers the total number of features +instances (minus missing values) as the number of trials, and the number of +of features below the sample medians as the number of successes.

+

There is a bit more detail in the vignette: vignette("testing-for-left-censorship", package = "ICIKendallTau")

+
+
+

See also

+ +
+ +
+

Examples

+
# this example has 80% missing due to left-censorship
+data(missing_dataset)
+missingness = test_left_censorship(missing_dataset)
+missingness$values
+#>   trials success class
+#> 1   1900    1520     A
+missingness$binomial_test
+#> 
+#> 	Exact binomial test
+#> 
+#> data:  total_success and total_trials
+#> number of successes = 1520, number of trials = 1900, p-value < 2.2e-16
+#> alternative hypothesis: true probability of success is greater than 0.5
+#> 95 percent confidence interval:
+#>  0.7843033 1.0000000
+#> sample estimates:
+#> probability of success 
+#>                    0.8 
+#> 
+
+
+
+
+ + +
+ + + +
+ + + + + + + diff --git a/docs/search.json b/docs/search.json index ce0b6fe..2129380 100644 --- a/docs/search.json +++ b/docs/search.json @@ -1 +1 @@ -[{"path":[]},{"path":"/CODE_OF_CONDUCT.html","id":"our-pledge","dir":"","previous_headings":"","what":"Our Pledge","title":"Contributor Covenant Code of Conduct","text":"members, contributors, leaders pledge make participation community harassment-free experience everyone, regardless age, body size, visible invisible disability, ethnicity, sex characteristics, gender identity expression, level experience, education, socio-economic status, nationality, personal appearance, race, religion, sexual identity orientation. pledge act interact ways contribute open, welcoming, diverse, inclusive, healthy community.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"our-standards","dir":"","previous_headings":"","what":"Our Standards","title":"Contributor Covenant Code of Conduct","text":"Examples behavior contributes positive environment community include: Demonstrating empathy kindness toward people respectful differing opinions, viewpoints, experiences Giving gracefully accepting constructive feedback Accepting responsibility apologizing affected mistakes, learning experience Focusing best just us individuals, overall community Examples unacceptable behavior include: use sexualized language imagery, sexual attention advances kind Trolling, insulting derogatory comments, personal political attacks Public private harassment Publishing others’ private information, physical email address, without explicit permission conduct reasonably considered inappropriate professional setting","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"enforcement-responsibilities","dir":"","previous_headings":"","what":"Enforcement Responsibilities","title":"Contributor Covenant Code of Conduct","text":"Community leaders responsible clarifying enforcing standards acceptable behavior take appropriate fair corrective action response behavior deem inappropriate, threatening, offensive, harmful. Community leaders right responsibility remove, edit, reject comments, commits, code, wiki edits, issues, contributions aligned Code Conduct, communicate reasons moderation decisions appropriate.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"scope","dir":"","previous_headings":"","what":"Scope","title":"Contributor Covenant Code of Conduct","text":"Code Conduct applies within community spaces, also applies individual officially representing community public spaces. Examples representing community include using official e-mail address, posting via official social media account, acting appointed representative online offline event.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"enforcement","dir":"","previous_headings":"","what":"Enforcement","title":"Contributor Covenant Code of Conduct","text":"Instances abusive, harassing, otherwise unacceptable behavior may reported community leaders responsible enforcement rflight79@gmail.com. complaints reviewed investigated promptly fairly. community leaders obligated respect privacy security reporter incident.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"enforcement-guidelines","dir":"","previous_headings":"","what":"Enforcement Guidelines","title":"Contributor Covenant Code of Conduct","text":"Community leaders follow Community Impact Guidelines determining consequences action deem violation Code Conduct:","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"id_1-correction","dir":"","previous_headings":"Enforcement Guidelines","what":"1. Correction","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Use inappropriate language behavior deemed unprofessional unwelcome community. Consequence: private, written warning community leaders, providing clarity around nature violation explanation behavior inappropriate. public apology may requested.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"id_2-warning","dir":"","previous_headings":"Enforcement Guidelines","what":"2. Warning","title":"Contributor Covenant Code of Conduct","text":"Community Impact: violation single incident series actions. Consequence: warning consequences continued behavior. interaction people involved, including unsolicited interaction enforcing Code Conduct, specified period time. includes avoiding interactions community spaces well external channels like social media. Violating terms may lead temporary permanent ban.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"id_3-temporary-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"3. Temporary Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: serious violation community standards, including sustained inappropriate behavior. Consequence: temporary ban sort interaction public communication community specified period time. public private interaction people involved, including unsolicited interaction enforcing Code Conduct, allowed period. Violating terms may lead permanent ban.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"id_4-permanent-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"4. Permanent Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Demonstrating pattern violation community standards, including sustained inappropriate behavior, harassment individual, aggression toward disparagement classes individuals. Consequence: permanent ban sort public interaction within community.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributor Covenant Code of Conduct","text":"Code Conduct adapted Contributor Covenant, version 2.0, available https://www.contributor-covenant.org/version/2/0/ code_of_conduct.html. Community Impact Guidelines inspired Mozilla’s code conduct enforcement ladder. answers common questions code conduct, see FAQ https://www.contributor-covenant.org/faq. Translations available https:// www.contributor-covenant.org/translations.","code":""},{"path":"/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"MIT License","title":"MIT License","text":"Copyright (c) 2021 Robert M Flight & Hunter NB Moseley Permission hereby granted, free charge, person obtaining copy software associated documentation files (“Software”), deal Software without restriction, including without limitation rights use, copy, modify, merge, publish, distribute, sublicense, /sell copies Software, permit persons Software furnished , subject following conditions: copyright notice permission notice shall included copies substantial portions Software. SOFTWARE PROVIDED “”, WITHOUT WARRANTY KIND, EXPRESS IMPLIED, INCLUDING LIMITED WARRANTIES MERCHANTABILITY, FITNESS PARTICULAR PURPOSE NONINFRINGEMENT. EVENT SHALL AUTHORS COPYRIGHT HOLDERS LIABLE CLAIM, DAMAGES LIABILITY, WHETHER ACTION CONTRACT, TORT OTHERWISE, ARISING , CONNECTION SOFTWARE USE DEALINGS SOFTWARE.","code":""},{"path":"/articles/ici-kendalltau.html","id":"problem","dir":"Articles","previous_headings":"","what":"Problem","title":"Information-Content-Informed Kendall Tau Correlation","text":"handle missing data (.e. NA’s) calculating correlation two variables. However, whether observation made semi-quantitative information many analytical measurements sensitivity limits. .e. many cases, missing observations “missing--random”, “missing---random” due falling detection limit. cases, NA informative.","code":""},{"path":"/articles/ici-kendalltau.html","id":"approach","dir":"Articles","previous_headings":"","what":"Approach","title":"Information-Content-Informed Kendall Tau Correlation","text":"Kendall Tau Correlation coefficient calculates correlation based number concordant discordant pairs: \\(\\tau = \\frac{ | pairs_{concordant} | - | pairs_{discordant} |}{\\binom{n}{2}}\\) pair two x-y data points. \\(x_i > x_j\\) \\(y_i > y_j\\) \\(x_i < x_j\\) \\(y_i < y_j\\) \\(x_i > x_j\\) \\(y_i < y_j\\) \\(x_i < x_j\\) \\(y_i > y_j\\) definitions can expanded handle missing observations: \\(x_i > x_j\\) \\(y_i > y_j\\) \\(x_i < x_j\\) \\(y_i < y_j\\) \\(x_i > x_j\\) \\(y_i \\& !y_j\\) \\(x_i < x_j\\) \\(!y_i \\& y_j\\) \\(x_i \\& !x_j\\) \\(y_i > y_j\\) \\(!x_i \\& x_j\\) \\(y_i < y_j\\) \\(x_i \\& !x_j\\) \\(y_i \\& !y_j\\) (used local perspective version) \\(x_i \\& x_j\\) \\(!y_i \\& y_j\\) (used local perspective version) \\(x_i > x_j\\) \\(y_i < y_j\\) \\(x_i < x_j\\) \\(y_i > y_j\\) \\(x_i > x_j\\) \\(!y_i \\& y_j\\) \\(x_i < x_j\\) \\(y_i \\& !y_j\\) \\(x_i \\& !x_j\\) \\(y_i < y_j\\) \\(!x_i \\& x_j\\) \\(y_i > y_j\\) \\(x_i \\& !x_j\\) \\(!y_i \\& y_j\\) (used local perspective version) \\(!x_i \\& x_j\\) \\(y_i \\& !y_j\\) (used local perspective version) Also data points missing x y values naturally reduce strength correlation value, since can neither concordant discordant another (NA, NA) pair, impact denominator. equivalent removing last two concordant discordant pair tests.","code":""},{"path":"/articles/ici-kendalltau.html","id":"handling-tied-values","dir":"Articles","previous_headings":"","what":"Handling Tied Values","title":"Information-Content-Informed Kendall Tau Correlation","text":"base Kendall tau correlation must adjusted handle tied values, ie. tau-b version equation. \\[\\tau = \\frac{ | pairs_{concordant} | - | pairs_{discordant} |}{\\sqrt{ ( n_0 - n_{xtie} ) ( n_0 - n_{ytie} )}} \\] : \\(n_0 = \\frac{n \\left ( n - 1 \\right )}{2}\\) \\(n_{xtie} = \\sum_{}^{} \\frac{t_{xi} \\left ( t_{xi} - 1 \\right )}{2}\\) \\(n_{ytie} = \\sum_{}^{} \\frac{t_{yi} \\left ( t_{yi} - 1 \\right )}{2}\\) \\(t_{xi}\\) - size ith group tied x values. \\(t_{yi}\\) - size ith group tied y values. local perspective, number NAs x y can treated group tied values calculation \\(n_{xtie}\\) \\(n_{ytie}\\), respectively.","code":""},{"path":"/articles/ici-kendalltau.html","id":"scaling-by-the-correlation-with-the-highest-information-content","dir":"Articles","previous_headings":"","what":"Scaling by the correlation with the highest information content","title":"Information-Content-Informed Kendall Tau Correlation","text":"generating correlation matrix (heatmap) large analytical datasets, number observations common can become quite low two variables. becomes advantageous scale pair variables highest information content. One objective scaling factor highest possible absolute correlation maximum information content observed across dataset, dividing maximum possible absolute correlation scale whole dataset appropriately. \\[maxcorr = \\frac{\\binom{n-m}{2} + n * m}{\\binom{n-m}{2} + n * m + \\binom{m}{2}}\\] : Choose two variables least number missing values across dataset. n length variables. formula based perfect correlation given number (NA,NA) pairs added.","code":""},{"path":"/articles/ici-kendalltau.html","id":"functions","dir":"Articles","previous_headings":"","what":"Functions","title":"Information-Content-Informed Kendall Tau Correlation","text":"functions implement include: option perspective control NA values influence ties. comparing multiple samples, likely want use perspective = \"global\". Rows features, columns samples. library(furrr) plan(multiprocess) Otherwise use single core.","code":""},{"path":"/articles/ici-kendalltau.html","id":"implementation","dir":"Articles","previous_headings":"","what":"Implementation","title":"Information-Content-Informed Kendall Tau Correlation","text":"turns , think really hard, truly necessary replace missing values vector value smaller minimum value one. local version, first remove common missing values vector. C++ implementation explicitly can speed, instead wrapping {stats::cor} function. also use double merge-sort algorithm, translating {scipy:: ::stats::kendalltau} function C++ using {Rcpp}.","code":""},{"path":"/articles/ici-kendalltau.html","id":"speed","dir":"Articles","previous_headings":"","what":"Speed","title":"Information-Content-Informed Kendall Tau Correlation","text":"","code":"x = rnorm(1000) y = rnorm(1000) library(microbenchmark) microbenchmark( cor(x, y, method = \"kendall\"), ici_kt(x, y, \"global\"), times = 5 ) #> Unit: microseconds #> expr min lq mean median #> cor(x, y, method = \"kendall\") 12781.169 13088.783 13795.1100 13290.629 #> ici_kt(x, y, \"global\") 261.498 304.518 335.7076 305.834 #> uq max neval #> 14382.628 15432.341 5 #> 327.014 479.674 5 all.equal(ici_kt(x, y, \"global\")[[1]], cor(x, y, method = \"kendall\")) #> [1] TRUE"},{"path":"/articles/ici-kendalltau.html","id":"running-many","dir":"Articles","previous_headings":"","what":"Running Many","title":"Information-Content-Informed Kendall Tau Correlation","text":"Just like R’s cor function, can also calculate correlations many variables. Let’s make fake data try .","code":"set.seed(1234) s1 = sort(rnorm(1000, mean = 100, sd = 10)) s2 = s1 + 10 s2[sample(length(s1), 100)] = s1[1:100] s3 = s1 s3[c(1:10, sample(length(s1), 5))] = NA matrix_1 = cbind(s1, s2, s3) r_1 = ici_kendalltau(matrix_1) r_1$cor #> s1 s2 s3 #> s1 1.0000000 0.8049209 0.9907488 #> s2 0.8049209 1.0000000 0.7956652 #> s3 0.9907488 0.7956652 0.9850000"},{"path":"/articles/ici-kendalltau.html","id":"parallelism","dir":"Articles","previous_headings":"","what":"Parallelism","title":"Information-Content-Informed Kendall Tau Correlation","text":"{future} {furrr} packages installed, also possible split set matrix comparisons across compute resources multiprocessing engine registered {future}.","code":"library(furrr) future::plan(multicore, workers = 4) r_2 = ici_kendalltau(matrix_1)"},{"path":"/articles/ici-kendalltau.html","id":"many-many-comparisons","dir":"Articles","previous_headings":"","what":"Many Many Comparisons","title":"Information-Content-Informed Kendall Tau Correlation","text":"case hundreds thousands comparisons done, result matrices can become , large, require lots memory storage. also inefficient, lower upper triangular components stored. alternative storage format data.frame, single row comparison performed. actually results stored internally, converted matrix form requested (default).s keep data.frame output, add argument return_matrix=FALSE call ici_kendalltau.","code":"r_3 = ici_kendalltau(matrix_1, return_matrix = FALSE) r_3$cor #> s1 s2 core raw pvalue taumax cor #> 1 s1 s2 1 0.8049209 0 1.0000000 0.8049209 #> 2 s1 s3 1 0.9907488 0 0.9998949 0.9907488 #> 3 s2 s3 1 0.7956652 0 0.9998949 0.7956652 #> 4 s1 s1 0 1.0000000 0 1.0000000 1.0000000 #> 5 s2 s2 0 1.0000000 0 1.0000000 1.0000000 #> 6 s3 s3 0 0.9850000 0 1.0000000 0.9850000"},{"path":"/articles/ici-kendalltau.html","id":"logging","dir":"Articles","previous_headings":"","what":"Logging","title":"Information-Content-Informed Kendall Tau Correlation","text":"possible log steps done much memory used (Linux least) correlations calculated. can useful running large sets correlations making sure much memory isn’t used, example. enable logging, {logger} package must installed. log_file supplied, one created current date time. default, ici_kendalltau also shows progress messages, want turn , can :","code":"enable_logging() enable_logging(\"/tmp/my_ici_run.log\") show_progress(FALSE)"},{"path":"/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Robert M Flight. Author, maintainer. Hunter NB Moseley. Author.","code":""},{"path":"/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Flight RM, Moseley HN (2024). ICIKendallTau: Calculates information-content-informed Kendall-tau. R package version 1.0.2, https://moseleybioinformaticslab.github.io/ICIKendallTauhttps://github.com/moseleybioinformaticslab/ICIKendallTau.","code":"@Manual{, title = {ICIKendallTau: Calculates information-content-informed Kendall-tau}, author = {Robert M Flight and Hunter NB Moseley}, year = {2024}, note = {R package version 1.0.2}, url = {https://moseleybioinformaticslab.github.io/ICIKendallTau https://github.com/moseleybioinformaticslab/ICIKendallTau}, }"},{"path":"/index.html","id":"icikendalltau","dir":"","previous_headings":"","what":"Calculates information-content-informed Kendall-tau","title":"Calculates information-content-informed Kendall-tau","text":"can see pkgdown site .","code":""},{"path":"/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Calculates information-content-informed Kendall-tau","text":"can install current version ICIKendallTau via GitHub: can also install Windows Mac binaries using r-universe:","code":"remotes::install_github(\"MoseleyBioinformaticsLab/ICIKendallTau\") options(repos = c( moseleybioinformaticslab = 'https://moseleybioinformaticslab.r-universe.dev', CRAN = \"https://cloud.r-project.org\")) install.packages(\"ICIKendallTau\")"},{"path":"/index.html","id":"problem","dir":"","previous_headings":"","what":"Problem","title":"Calculates information-content-informed Kendall-tau","text":"handle missing data (.e. NA’s) calculating correlation two variables. However, whether observation present missing semi-quantitative information many analytical measurements sensitivity limits. .e. many cases, missing observations “missing--random”, “missing---random” due falling detection limit. cases, NA informative. Therefore, analytical measurements (gene expression, proteomics, metabolomics), missing measurements included, contribute correlation. want read solve problem, see package vignette.","code":""},{"path":"/index.html","id":"package-functions","dir":"","previous_headings":"","what":"Package Functions","title":"Calculates information-content-informed Kendall-tau","text":"functions implement include: option perspective control NA values influence ties. comparing samples, likely want use perspective = \"global\". Rows features, columns samples. library(furrr) plan(multiprocess) Otherwise use single core.","code":""},{"path":"/index.html","id":"examples","dir":"","previous_headings":"","what":"Examples","title":"Calculates information-content-informed Kendall-tau","text":"common case large matrix independent samples (columns) measured features samples (.e. gene expression). make artificial data show correlation changes introduce missingness. Now introduce missing values low end one. just simplest thing introduce NA values bottom set.","code":"set.seed(1234) library(ICIKendallTau) s1 = sort(rnorm(1000, mean = 100, sd = 10)) s2 = s1 + 10 matrix_1 = cbind(s1, s2) r_1 = ici_kendalltau(matrix_1) r_1$cor #> s1 s2 #> s1 1 1 #> s2 1 1 s3 = s1 s3[sample(100, 50)] = NA s4 = s2 s4[sample(100, 50)] = NA matrix_2 = cbind(s3, s4) r_2 = ici_kendalltau(matrix_2) r_2$cor #> s3 s4 #> s3 1.0000000 0.9944616 #> s4 0.9944616 1.0000000"},{"path":"/index.html","id":"is-it-fast","dir":"","previous_headings":"","what":"Is It Fast?","title":"Calculates information-content-informed Kendall-tau","text":"C++ code implementation (thanks {Rcpp}!) based SciPy implementation, uses two merge sorts ranks vector, looks differences . fastest method know , complexity O(nlogn). naive way computing , explicitly examines pairs, complexity n^2. implementation compared {pcaPP::cov.fk} function, use {Rcpp} inefficient copying vectors makes 3X slower one. honestly isn’t bad. case 40,000 features, average time modern CPU 14 milliseconds. course, want use calculate Kendall-tau-b without incorporating missingness, can just fine well. also provide kt_fast function, want something treats NA values similarly stats::cor.","code":"library(microbenchmark) x = rnorm(1000) y = rnorm(1000) x2 = rnorm(40000) y2 = rnorm(40000) library(microbenchmark) microbenchmark( cor(x, y, method = \"kendall\"), ici_kt(x, y, \"global\"), ici_kt(x2, y2, \"global\"), times = 5 ) #> Unit: microseconds #> expr min lq mean median uq max #> cor(x, y, method = \"kendall\") 11506.697 11670.094 12169.6628 12006.418 12482.883 13182.222 #> ici_kt(x, y, \"global\") 243.866 250.125 294.6542 275.104 320.058 384.118 #> ici_kt(x2, y2, \"global\") 13467.011 13739.312 14658.5050 14945.446 14987.140 16153.616 #> neval #> 5 #> 5 #> 5 k_tau = ici_kt(x, y, \"global\") all.equal(k_tau[[1]] ,cor(x, y, method = \"kendall\")) #> [1] TRUE k_tau_fast = kt_fast(x, y) k_tau_fast #> tau pvalue #> -0.003411411 0.871672260"},{"path":"/index.html","id":"parallelism","dir":"","previous_headings":"","what":"Parallelism","title":"Calculates information-content-informed Kendall-tau","text":"{future} {furrr} packages installed, also possible split set matrix comparisons across compute resources multiprocessing engine registered {future}.","code":"library(furrr) future::plan(multicore, workers = 4) r_3 = ici_kendalltau(matrix_2)"},{"path":"/index.html","id":"many-many-comparisons","dir":"","previous_headings":"","what":"Many Many Comparisons","title":"Calculates information-content-informed Kendall-tau","text":"case hundreds thousands comparisons done, result matrices can become , large, require lots memory storage. also inefficient, lower upper triangular components stored. alternative storage format data.frame, single row comparison performed. actually results stored internally, converted matrix form requested (default).s keep data.frame output, add argument return_matrix=FALSE call ici_kendalltau.","code":"r_4 = ici_kendalltau(matrix_2, return_matrix = FALSE) r_4 #> $cor #> s1 s2 core raw pvalue taumax cor #> 1 s3 s4 1 0.9924359 0 0.997963 0.9944616 #> 2 s3 s3 0 1.0000000 0 1.000000 1.0000000 #> 3 s4 s4 0 1.0000000 0 1.000000 1.0000000 #> #> $run_time #> [1] 0.01606894"},{"path":"/index.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of Conduct","title":"Calculates information-content-informed Kendall-tau","text":"Please note ICIKendallTau project released Contributor Code Conduct. contributing project, agree abide terms.","code":""},{"path":"/reference/cor_matrix_2_long_df.html","id":null,"dir":"Reference","previous_headings":"","what":"convert matrix to data.frame — cor_matrix_2_long_df","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"Given square correlation matrix, converts long data.frame, three columns.","code":""},{"path":"/reference/cor_matrix_2_long_df.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"","code":"cor_matrix_2_long_df(in_matrix)"},{"path":"/reference/cor_matrix_2_long_df.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"in_matrix correlation matrix","code":""},{"path":"/reference/cor_matrix_2_long_df.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"data.frame","code":""},{"path":"/reference/cor_matrix_2_long_df.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"data.frame contains three columns: s1: first entry comparison s2: second entry comparison cor: correlation value","code":""},{"path":"/reference/disable_logging.html","id":null,"dir":"Reference","previous_headings":"","what":"turn logging off — disable_logging","title":"turn logging off — disable_logging","text":"may good reasons turn logging turned . basically tells package logger available.","code":""},{"path":"/reference/disable_logging.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"turn logging off — disable_logging","text":"","code":"disable_logging()"},{"path":"/reference/enable_logging.html","id":null,"dir":"Reference","previous_headings":"","what":"turn logging on — enable_logging","title":"turn logging on — enable_logging","text":"Choose enable logging, specific file desired.","code":""},{"path":"/reference/enable_logging.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"turn logging on — enable_logging","text":"","code":"enable_logging(log_file = NULL, memory = FALSE)"},{"path":"/reference/enable_logging.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"turn logging on — enable_logging","text":"log_file file log memory provide memory logging ? available Linux MacOS","code":""},{"path":"/reference/enable_logging.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"turn logging on — enable_logging","text":"Uses logger package hood, suggested dependencies. logging enabled nice see things starting stopping, exactly done, without needing write messages console. especially useful getting errors, really see , can add \"memory\" logging see running memory. Default log file pattern: YYYY.MM.DD.HH.MM.SS_ICIKendallTau_run.log","code":""},{"path":"/reference/ici_kendalltau.html","id":null,"dir":"Reference","previous_headings":"","what":"information-content-informed kendall tau — ici_kendalltau","title":"information-content-informed kendall tau — ici_kendalltau","text":"Given data-matrix, computes information-theoretic Kendall-tau-b samples.","code":""},{"path":"/reference/ici_kendalltau.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"information-content-informed kendall tau — ici_kendalltau","text":"","code":"ici_kendalltau( data_matrix, global_na = c(NA, Inf, 0), perspective = \"global\", scale_max = TRUE, diag_good = TRUE, include_only = NULL, check_timing = FALSE, return_matrix = TRUE )"},{"path":"/reference/ici_kendalltau.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"information-content-informed kendall tau — ici_kendalltau","text":"data_matrix samples columns, features rows global_na globally, treated NA? perspective treat missing data denominator ties, see details scale_max everything scaled compared maximum correlation? diag_good diagonal entries reflect many entries sample \"good\"? include_only run correlations include members (vector) combinations (list data.frame) check_timing try estimate run time full dataset? (default FALSE) return_matrix data.frame matrix result returned?","code":""},{"path":"/reference/ici_kendalltau.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"information-content-informed kendall tau — ici_kendalltau","text":"list cor, raw, pval, taumax","code":""},{"path":"/reference/ici_kendalltau.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"information-content-informed kendall tau — ici_kendalltau","text":"details, see ICI-Kendall-tau vignette browseVignettes(\"ICIKendallTau\") default global_na includes values data replace NA Kendall-tau calculation. default global_na = c(NA, Inf, 0). want replace something 0, example, might use global_na = c(NA, Inf, -2), values -2 replaced instead 0. check_timing = TRUE, 5 random pairwise comparisons run generate timings single core, estimates long full set take calculated. data returned data.frame, low side, provide good idea long data take. Returned list containing matrices : cor: scaled correlations raw: raw kendall-tau correlations pval: p-values taumax: theoretical maximum kendall-tau value possible Eventually, plan provide two parameters replacing values, feature_na feature specific NA values sample_na sample specific NA values.","code":""},{"path":"/reference/ici_kendalltau.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"information-content-informed kendall tau — ici_kendalltau","text":"","code":"if (FALSE) { # not run set.seed(1234) s1 = sort(rnorm(1000, mean = 100, sd = 10)) s2 = s1 + 10 matrix_1 = cbind(s1, s2) r_1 = ici_kendalltau(matrix_1) r_1$cor # s1 s2 # s1 1 1 # s2 1 1 names(r_1) # \"cor\", \"raw\", \"pval\", \"taumax\", \"keep\", \"run_time\" s3 = s1 s3[sample(100, 50)] = NA s4 = s2 s4[sample(100, 50)] = NA matrix_2 = cbind(s3, s4) r_2 = ici_kendalltau(matrix_2) r_2$cor # s3 s4 # s3 1.0000000 0.9944616 # s4 0.9944616 1.0000000 # using include_only set.seed(1234) x = t(matrix(rnorm(5000), nrow = 100, ncol = 50)) colnames(x) = paste0(\"s\", seq(1, nrow(x))) # only calculate correlations of other columns with \"s1\" include_s1 = \"s1\" s1_only = ici_kendalltau(x, include_only = include_s1) # include s1 and s3 things both include_s1s3 = c(\"s1\", \"s3\") s1s3_only = ici_kendalltau(x, include_only = include_s1s3) # only specify certain pairs either as a list include_pairs = list(g1 = \"s1\", g2 = c(\"s2\", \"s3\")) s1_other = ici_kendalltau(x, include_only = include_pairs) # or a data.frame include_df = as.data.frame(list(g1 = \"s1\", g2 = c(\"s2\", \"s3\"))) s1_df = ici_kendalltau(x, include_only = include_df) }"},{"path":"/reference/ici_kendalltau_ref.html","id":null,"dir":"Reference","previous_headings":"","what":"information-content-informed kendall tau — ici_kendalltau_ref","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"Given data-matrix, computes information-content-informed (ICI) Kendall-tau-b samples.","code":""},{"path":"/reference/ici_kendalltau_ref.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"","code":"ici_kendalltau_ref( data_matrix, global_na = c(NA, Inf, 0), zero_value = 0, perspective = \"global\", scale_max = TRUE, diag_good = TRUE, progress = FALSE )"},{"path":"/reference/ici_kendalltau_ref.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"data_matrix samples columns, features rows global_na values treated missing (NA)? zero_value actual zero value? perspective treat missing data denominator ties, see details scale_max everything scaled compared maximum correlation? diag_good diagonal entries reflect many entries sample \"good\"? progress progress displayed.","code":""},{"path":"/reference/ici_kendalltau_ref.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"numeric","code":""},{"path":"/reference/ici_kendalltau_ref.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"details, see ICI-Kendall-tau vignette: vignette(\"ici-kendalltau\", package = \"ICIKendallTau\")","code":""},{"path":"/reference/ici_kt.html","id":null,"dir":"Reference","previous_headings":"","what":"Calculates ici-kendall-tau — ici_kt","title":"Calculates ici-kendall-tau — ici_kt","text":"Calculates ici-kendall-tau","code":""},{"path":"/reference/ici_kt.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Calculates ici-kendall-tau — ici_kt","text":"","code":"ici_kt( x, y, perspective = \"local\", alternative = \"two.sided\", continuity = FALSE, output = \"simple\" )"},{"path":"/reference/ici_kt.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Calculates ici-kendall-tau — ici_kt","text":"x numeric vector y numeric vector perspective consider \"local\" \"global\" perspective? alternative alternative p-value test? continuity logical: true, continuity correction used output used control reporting values debugging","code":""},{"path":"/reference/ici_kt.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Calculates ici-kendall-tau — ici_kt","text":"kendall tau correlation, p-value, max-correlation","code":""},{"path":"/reference/ici_kt.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Calculates ici-kendall-tau — ici_kt","text":"Calculates information-content-informed Kendall-tau correlation measure. correlation based concordant discordant ranked pairs, like Kendall-tau, also includes missing values (NA). Missing values assumed primarily due lack detection due instrumental sensitivity, therefore encode information. details see ICI-Kendall-tau vignette: browseVignettes(\"ICIKendallTau\")","code":""},{"path":"/reference/ici_kt.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Calculates ici-kendall-tau — ici_kt","text":"","code":"x = sort(rnorm(100)) y = x + 1 y2 = y y2[1:10] = NA ici_kt(x, y) #> tau pvalue tau_max #> 1.000000e+00 3.480281e-49 1.000000e+00 ici_kt(x, y2, \"global\") #> tau pvalue tau_max #> 9.954442e-01 2.228308e-48 9.954442e-01 ici_kt(x, y2) #> tau pvalue tau_max #> 9.954442e-01 2.228308e-48 9.954442e-01"},{"path":"/reference/kt_fast.html","id":null,"dir":"Reference","previous_headings":"","what":"fast kendall tau — kt_fast","title":"fast kendall tau — kt_fast","text":"Uses underlying c++ implementation ici_kt provide fast version Kendall-tau correlation.","code":""},{"path":"/reference/kt_fast.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"fast kendall tau — kt_fast","text":"","code":"kt_fast(x, y = NULL, use = \"everything\", return_matrix = TRUE)"},{"path":"/reference/kt_fast.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"fast kendall tau — kt_fast","text":"x numeric vector, matrix, data frame. y NULL (default) vector. use optional character string giving method computing correlations presence missing values. must (abbreviation ) one strings \"everything\", \".obs\", \"complete.obs\", \"pairwise.complete.obs\". return_matrix matrices values returned, long data.frame","code":""},{"path":"/reference/kt_fast.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"fast kendall tau — kt_fast","text":"named vector list matrices.","code":""},{"path":"/reference/kt_fast.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"fast kendall tau — kt_fast","text":"Although interface mostly identical built-stats::cor method, differences. providing x y, assumed single vectors. NA values present, function error, either remove return NA, depending option. \"na..complete\" valid option use. named vector named list matrices returned, tau pvalue values.","code":""},{"path":"/reference/log_memory.html","id":null,"dir":"Reference","previous_headings":"","what":"log memory usage — log_memory","title":"log memory usage — log_memory","text":"Logs amount memory used log file available, generating warnings amount RAM hits zero.","code":""},{"path":"/reference/log_memory.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"log memory usage — log_memory","text":"","code":"log_memory()"},{"path":"/reference/log_message.html","id":null,"dir":"Reference","previous_headings":"","what":"log messages — log_message","title":"log messages — log_message","text":"log_appender available, logs given message info level.","code":""},{"path":"/reference/log_message.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"log messages — log_message","text":"","code":"log_message(message_string)"},{"path":"/reference/log_message.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"log messages — log_message","text":"message_string string put message","code":""},{"path":"/reference/long_df_2_cor_matrix.html","id":null,"dir":"Reference","previous_headings":"","what":"convert data.frame to matrix — long_df_2_cor_matrix","title":"convert data.frame to matrix — long_df_2_cor_matrix","text":"Given long data.frame, converts possibly square correlation matrix","code":""},{"path":"/reference/long_df_2_cor_matrix.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"convert data.frame to matrix — long_df_2_cor_matrix","text":"","code":"long_df_2_cor_matrix(long_df, is_square = TRUE)"},{"path":"/reference/long_df_2_cor_matrix.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"convert data.frame to matrix — long_df_2_cor_matrix","text":"long_df long data.frame is_square square matrix?","code":""},{"path":"/reference/long_df_2_cor_matrix.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"convert data.frame to matrix — long_df_2_cor_matrix","text":"matrix","code":""},{"path":"/reference/pairwise_completeness.html","id":null,"dir":"Reference","previous_headings":"","what":"pairwise completeness — pairwise_completeness","title":"pairwise completeness — pairwise_completeness","text":"Calculates completeness two samples using \"\", entry missing either X \"\" Y.","code":""},{"path":"/reference/pairwise_completeness.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"pairwise completeness — pairwise_completeness","text":"","code":"pairwise_completeness( data_matrix, global_na = c(NA, Inf, 0), include_only = NULL, return_matrix = TRUE )"},{"path":"/reference/pairwise_completeness.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"pairwise completeness — pairwise_completeness","text":"data_matrix samples columns, features rows global_na globally, treated NA? include_only certain comparisons ? return_matrix matrix data.frame returned?","code":""},{"path":"/reference/pairwise_completeness.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"pairwise completeness — pairwise_completeness","text":"matrix degree completeness","code":""},{"path":"/reference/show_progress.html","id":null,"dir":"Reference","previous_headings":"","what":"turn progress on off — show_progress","title":"turn progress on off — show_progress","text":"Allow user turn progress messages console . Default provide messages console.","code":""},{"path":"/reference/show_progress.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"turn progress on off — show_progress","text":"","code":"show_progress(progress = TRUE)"},{"path":"/reference/show_progress.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"turn progress on off — show_progress","text":"progress logical ","code":""},{"path":"/news/index.html","id":"icikendalltau-100","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 1.0.0","title":"ICIKendallTau 1.0.0","text":"Calculates correlation columns matrix, rows.","code":""},{"path":"/news/index.html","id":"icikendalltau-0320","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.3.20","title":"ICIKendallTau 0.3.20","text":"kt_fast now uses data.frame format output ici_kendalltau, returns matrix default. data.frame useful large amounts comparisons run.","code":""},{"path":"/news/index.html","id":"icikendalltau-030","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.3.0","title":"ICIKendallTau 0.3.0","text":"Handling parallel execution differently avoid really large matrix issues core. Introduces return_matrix parameter ici_kendalltau allows return results form data.frame instead lists matrices.","code":""},{"path":"/news/index.html","id":"icikendalltau-0210","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.2.10","title":"ICIKendallTau 0.2.10","text":"Provide kt_fast function handles missing NA values similarly stats::cor function, uses ici_kt fast function underneath.","code":""},{"path":"/news/index.html","id":"icikendalltau-028","dir":"Changelog","previous_headings":"","what":"ICIKendalltau 0.2.8","title":"ICIKendalltau 0.2.8","text":"Made error outputs length default output containing NA. Check case one variables ici_kt identical arguments, warns user returns NA.","code":""},{"path":"/news/index.html","id":"icikendalltau-021","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.2.1","title":"ICIKendallTau 0.2.1","text":"Added new argument include_only ici_kendalltau allows user define pairwise correlations actually .","code":""},{"path":"/news/index.html","id":"icikendalltau-0117","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.1.17","title":"ICIKendallTau 0.1.17","text":"switched theme. updated installation instructions use r-universe.","code":""},{"path":"/news/index.html","id":"icikendalltau-0116","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.1.16","title":"ICIKendallTau 0.1.16","text":"updating documentation examples","code":""},{"path":"/news/index.html","id":"icikendalltau-014","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.1.4","title":"ICIKendallTau 0.1.4","text":"Switched pairwise_completeness also use global_na parameter. Oh yes, function pairwise_completeness enable scaling completeness two samples.","code":""},{"path":"/news/index.html","id":"icikendalltau-012","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.1.2","title":"ICIKendallTau 0.1.2","text":"Updated API use single variable, global_na defines values set NA correlation calculation. big API change, bumped version 0.1.","code":""},{"path":"/news/index.html","id":"icikendalltau-006","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.6","title":"ICIKendallTau 0.0.6","text":"Fixing bug 55,000 elements vector, match overflows 32 bit 64 bit, results make sense.","code":""},{"path":"/news/index.html","id":"icikendalltau-005","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.5","title":"ICIKendallTau 0.0.5","text":"Fixed bug instead returning two element vector, returned zero length value. probably happened one entries contained NA values, tried pass “vectors” less two entries.","code":""},{"path":"/news/index.html","id":"icikendalltau-004","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.4","title":"ICIKendallTau 0.0.4","text":"Fixing things came R CMD check documentation. good now (hope).","code":""},{"path":"/news/index.html","id":"icikendalltau-003","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.3","title":"ICIKendallTau 0.0.3","text":"Added tests! Removed bunch code wasn’t necessary using incorrect formula’s, correct version ici_kt_pairs function reference purposes.","code":""},{"path":"/news/index.html","id":"icikendalltau-002","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.2","title":"ICIKendallTau 0.0.2","text":"Fixed issue warning issued {furrr} installed.","code":""},{"path":"/news/index.html","id":"icikendalltau-001","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.1","title":"ICIKendallTau 0.0.1","text":"First release. ’s tested used rather thoroughly , ’d say ’s still rather alpha. Even though use time . Added NEWS.md file track changes package.","code":""}] +[{"path":[]},{"path":"/CODE_OF_CONDUCT.html","id":"our-pledge","dir":"","previous_headings":"","what":"Our Pledge","title":"Contributor Covenant Code of Conduct","text":"members, contributors, leaders pledge make participation community harassment-free experience everyone, regardless age, body size, visible invisible disability, ethnicity, sex characteristics, gender identity expression, level experience, education, socio-economic status, nationality, personal appearance, race, religion, sexual identity orientation. pledge act interact ways contribute open, welcoming, diverse, inclusive, healthy community.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"our-standards","dir":"","previous_headings":"","what":"Our Standards","title":"Contributor Covenant Code of Conduct","text":"Examples behavior contributes positive environment community include: Demonstrating empathy kindness toward people respectful differing opinions, viewpoints, experiences Giving gracefully accepting constructive feedback Accepting responsibility apologizing affected mistakes, learning experience Focusing best just us individuals, overall community Examples unacceptable behavior include: use sexualized language imagery, sexual attention advances kind Trolling, insulting derogatory comments, personal political attacks Public private harassment Publishing others’ private information, physical email address, without explicit permission conduct reasonably considered inappropriate professional setting","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"enforcement-responsibilities","dir":"","previous_headings":"","what":"Enforcement Responsibilities","title":"Contributor Covenant Code of Conduct","text":"Community leaders responsible clarifying enforcing standards acceptable behavior take appropriate fair corrective action response behavior deem inappropriate, threatening, offensive, harmful. Community leaders right responsibility remove, edit, reject comments, commits, code, wiki edits, issues, contributions aligned Code Conduct, communicate reasons moderation decisions appropriate.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"scope","dir":"","previous_headings":"","what":"Scope","title":"Contributor Covenant Code of Conduct","text":"Code Conduct applies within community spaces, also applies individual officially representing community public spaces. Examples representing community include using official e-mail address, posting via official social media account, acting appointed representative online offline event.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"enforcement","dir":"","previous_headings":"","what":"Enforcement","title":"Contributor Covenant Code of Conduct","text":"Instances abusive, harassing, otherwise unacceptable behavior may reported community leaders responsible enforcement rflight79@gmail.com. complaints reviewed investigated promptly fairly. community leaders obligated respect privacy security reporter incident.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"enforcement-guidelines","dir":"","previous_headings":"","what":"Enforcement Guidelines","title":"Contributor Covenant Code of Conduct","text":"Community leaders follow Community Impact Guidelines determining consequences action deem violation Code Conduct:","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"id_1-correction","dir":"","previous_headings":"Enforcement Guidelines","what":"1. Correction","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Use inappropriate language behavior deemed unprofessional unwelcome community. Consequence: private, written warning community leaders, providing clarity around nature violation explanation behavior inappropriate. public apology may requested.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"id_2-warning","dir":"","previous_headings":"Enforcement Guidelines","what":"2. Warning","title":"Contributor Covenant Code of Conduct","text":"Community Impact: violation single incident series actions. Consequence: warning consequences continued behavior. interaction people involved, including unsolicited interaction enforcing Code Conduct, specified period time. includes avoiding interactions community spaces well external channels like social media. Violating terms may lead temporary permanent ban.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"id_3-temporary-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"3. Temporary Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: serious violation community standards, including sustained inappropriate behavior. Consequence: temporary ban sort interaction public communication community specified period time. public private interaction people involved, including unsolicited interaction enforcing Code Conduct, allowed period. Violating terms may lead permanent ban.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"id_4-permanent-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"4. Permanent Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Demonstrating pattern violation community standards, including sustained inappropriate behavior, harassment individual, aggression toward disparagement classes individuals. Consequence: permanent ban sort public interaction within community.","code":""},{"path":"/CODE_OF_CONDUCT.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributor Covenant Code of Conduct","text":"Code Conduct adapted Contributor Covenant, version 2.0, available https://www.contributor-covenant.org/version/2/0/ code_of_conduct.html. Community Impact Guidelines inspired Mozilla’s code conduct enforcement ladder. answers common questions code conduct, see FAQ https://www.contributor-covenant.org/faq. Translations available https:// www.contributor-covenant.org/translations.","code":""},{"path":"/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"MIT License","title":"MIT License","text":"Copyright (c) Robert M Flight & Hunter NB Moseley Permission hereby granted, free charge, person obtaining copy software associated documentation files (“Software”), deal Software without restriction, including without limitation rights use, copy, modify, merge, publish, distribute, sublicense, /sell copies Software, permit persons Software furnished , subject following conditions: copyright notice permission notice shall included copies substantial portions Software. SOFTWARE PROVIDED “”, WITHOUT WARRANTY KIND, EXPRESS IMPLIED, INCLUDING LIMITED WARRANTIES MERCHANTABILITY, FITNESS PARTICULAR PURPOSE NONINFRINGEMENT. EVENT SHALL AUTHORS COPYRIGHT HOLDERS LIABLE CLAIM, DAMAGES LIABILITY, WHETHER ACTION CONTRACT, TORT OTHERWISE, ARISING , CONNECTION SOFTWARE USE DEALINGS SOFTWARE.","code":""},{"path":"/articles/ici-kendalltau.html","id":"problem","dir":"Articles","previous_headings":"","what":"Problem","title":"Information-Content-Informed Kendall Tau Correlation","text":"handle missing data (.e. NA’s) calculating correlation two variables. However, whether observation made semi-quantitative information many analytical measurements sensitivity limits. .e. many cases, missing observations “missing--random”, “missing---random” due falling detection limit. cases, NA informative.","code":""},{"path":"/articles/ici-kendalltau.html","id":"approach","dir":"Articles","previous_headings":"","what":"Approach","title":"Information-Content-Informed Kendall Tau Correlation","text":"Kendall Tau Correlation coefficient calculates correlation based number concordant discordant pairs: \\(\\tau = \\frac{ | pairs_{concordant} | - | pairs_{discordant} |}{\\binom{n}{2}}\\) pair two x-y data points. \\(x_i > x_j\\) \\(y_i > y_j\\) \\(x_i < x_j\\) \\(y_i < y_j\\) \\(x_i > x_j\\) \\(y_i < y_j\\) \\(x_i < x_j\\) \\(y_i > y_j\\) definitions can expanded handle missing observations: \\(x_i > x_j\\) \\(y_i > y_j\\) \\(x_i < x_j\\) \\(y_i < y_j\\) \\(x_i > x_j\\) \\(y_i \\& !y_j\\) \\(x_i < x_j\\) \\(!y_i \\& y_j\\) \\(x_i \\& !x_j\\) \\(y_i > y_j\\) \\(!x_i \\& x_j\\) \\(y_i < y_j\\) \\(x_i \\& !x_j\\) \\(y_i \\& !y_j\\) (used local perspective version) \\(x_i \\& x_j\\) \\(!y_i \\& y_j\\) (used local perspective version) \\(x_i > x_j\\) \\(y_i < y_j\\) \\(x_i < x_j\\) \\(y_i > y_j\\) \\(x_i > x_j\\) \\(!y_i \\& y_j\\) \\(x_i < x_j\\) \\(y_i \\& !y_j\\) \\(x_i \\& !x_j\\) \\(y_i < y_j\\) \\(!x_i \\& x_j\\) \\(y_i > y_j\\) \\(x_i \\& !x_j\\) \\(!y_i \\& y_j\\) (used local perspective version) \\(!x_i \\& x_j\\) \\(y_i \\& !y_j\\) (used local perspective version) Also data points missing x y values naturally reduce strength correlation value, since can neither concordant discordant another (NA, NA) pair, impact denominator. equivalent removing last two concordant discordant pair tests.","code":""},{"path":"/articles/ici-kendalltau.html","id":"handling-tied-values","dir":"Articles","previous_headings":"","what":"Handling Tied Values","title":"Information-Content-Informed Kendall Tau Correlation","text":"base Kendall tau correlation must adjusted handle tied values, ie. tau-b version equation. \\[\\tau = \\frac{ | pairs_{concordant} | - | pairs_{discordant} |}{\\sqrt{ ( n_0 - n_{xtie} ) ( n_0 - n_{ytie} )}} \\] : \\(n_0 = \\frac{n \\left ( n - 1 \\right )}{2}\\) \\(n_{xtie} = \\sum_{}^{} \\frac{t_{xi} \\left ( t_{xi} - 1 \\right )}{2}\\) \\(n_{ytie} = \\sum_{}^{} \\frac{t_{yi} \\left ( t_{yi} - 1 \\right )}{2}\\) \\(t_{xi}\\) - size ith group tied x values. \\(t_{yi}\\) - size ith group tied y values. local perspective, number NAs x y can treated group tied values calculation \\(n_{xtie}\\) \\(n_{ytie}\\), respectively.","code":""},{"path":"/articles/ici-kendalltau.html","id":"scaling-by-the-correlation-with-the-highest-information-content","dir":"Articles","previous_headings":"","what":"Scaling by the correlation with the highest information content","title":"Information-Content-Informed Kendall Tau Correlation","text":"generating correlation matrix (heatmap) large analytical datasets, number observations common can become quite low two variables. becomes advantageous scale pair variables highest information content. One objective scaling factor highest possible absolute correlation maximum information content observed across dataset, dividing maximum possible absolute correlation scale whole dataset appropriately. \\[maxcorr = \\frac{\\binom{n-m}{2} + n * m}{\\binom{n-m}{2} + n * m + \\binom{m}{2}}\\] : Choose two variables least number missing values across dataset. n length variables. formula based perfect correlation given number (NA,NA) pairs added.","code":""},{"path":"/articles/ici-kendalltau.html","id":"functions","dir":"Articles","previous_headings":"","what":"Functions","title":"Information-Content-Informed Kendall Tau Correlation","text":"functions implement include: option perspective control NA values influence ties. comparing multiple samples, likely want use perspective = \"global\". Rows features, columns samples. library(furrr) plan(multiprocess) Otherwise use single core. ’ve also included function testing missingness data comes left-censorship, test_left_censorship. walk creating example data testing vignette Testing Left Censorship.","code":""},{"path":"/articles/ici-kendalltau.html","id":"implementation","dir":"Articles","previous_headings":"","what":"Implementation","title":"Information-Content-Informed Kendall Tau Correlation","text":"turns , think really hard, truly necessary replace missing values vector value smaller minimum value one. local version, first remove common missing values vector. C++ implementation explicitly can speed, instead wrapping {stats::cor} function. also use double merge-sort algorithm, translating {scipy:: ::stats::kendalltau} function C++ using {Rcpp}.","code":""},{"path":"/articles/ici-kendalltau.html","id":"speed","dir":"Articles","previous_headings":"","what":"Speed","title":"Information-Content-Informed Kendall Tau Correlation","text":"","code":"x = rnorm(1000) y = rnorm(1000) library(microbenchmark) microbenchmark( cor(x, y, method = \"kendall\"), ici_kt(x, y, \"global\"), times = 5 ) #> Unit: microseconds #> expr min lq mean median #> cor(x, y, method = \"kendall\") 11716.612 12670.75 13230.1676 13124.263 #> ici_kt(x, y, \"global\") 231.868 233.36 276.8498 235.229 #> uq max neval #> 13485.116 15154.096 5 #> 268.721 415.071 5 all.equal(ici_kt(x, y, \"global\")[[1]], cor(x, y, method = \"kendall\")) #> [1] TRUE"},{"path":"/articles/ici-kendalltau.html","id":"running-many","dir":"Articles","previous_headings":"","what":"Running Many","title":"Information-Content-Informed Kendall Tau Correlation","text":"Just like R’s cor function, can also calculate correlations many variables. Let’s make fake data try .","code":"set.seed(1234) s1 = sort(rnorm(1000, mean = 100, sd = 10)) s2 = s1 + 10 s2[sample(length(s1), 100)] = s1[1:100] s3 = s1 s3[c(1:10, sample(length(s1), 5))] = NA matrix_1 = cbind(s1, s2, s3) r_1 = ici_kendalltau(matrix_1) r_1$cor #> s1 s2 s3 #> s1 1.0000000 0.8049209 0.9907488 #> s2 0.8049209 1.0000000 0.7956652 #> s3 0.9907488 0.7956652 0.9850000"},{"path":"/articles/ici-kendalltau.html","id":"parallelism","dir":"Articles","previous_headings":"","what":"Parallelism","title":"Information-Content-Informed Kendall Tau Correlation","text":"{future} {furrr} packages installed, also possible split set matrix comparisons across compute resources multiprocessing engine registered {future}.","code":"library(furrr) future::plan(multicore, workers = 4) r_2 = ici_kendalltau(matrix_1)"},{"path":"/articles/ici-kendalltau.html","id":"many-many-comparisons","dir":"Articles","previous_headings":"","what":"Many Many Comparisons","title":"Information-Content-Informed Kendall Tau Correlation","text":"case hundreds thousands comparisons done, result matrices can become , large, require lots memory storage. also inefficient, lower upper triangular components stored. alternative storage format data.frame, single row comparison performed. actually results stored internally, converted matrix form requested (default). keep data.frame output, add argument return_matrix=FALSE call ici_kendalltau.","code":"r_3 = ici_kendalltau(matrix_1, return_matrix = FALSE) r_3$cor #> s1 s2 core raw pvalue taumax cor #> 1 s1 s2 1 0.8049209 0 1.0000000 0.8049209 #> 2 s1 s3 1 0.9907488 0 0.9998949 0.9907488 #> 3 s2 s3 1 0.7956652 0 0.9998949 0.7956652 #> 4 s1 s1 0 1.0000000 0 1.0000000 1.0000000 #> 5 s2 s2 0 1.0000000 0 1.0000000 1.0000000 #> 6 s3 s3 0 0.9850000 0 1.0000000 0.9850000"},{"path":"/articles/ici-kendalltau.html","id":"logging","dir":"Articles","previous_headings":"","what":"Logging","title":"Information-Content-Informed Kendall Tau Correlation","text":"possible log steps done much memory used (Linux least) correlations calculated. can useful running large sets correlations making sure much memory isn’t used, example. enable logging, {logger} package must installed. log_file supplied, one created current date time. default, ici_kendalltau also shows progress messages, want turn , can :","code":"enable_logging() enable_logging(\"/tmp/my_ici_run.log\") show_progress(FALSE)"},{"path":"/articles/testing-for-left-censorship.html","id":"why","dir":"Articles","previous_headings":"","what":"Why?","title":"Testing for Left Censorship","text":"{ICIKendallTau} specific assumption, missing values largely due limit detection, result left-censorship. Therefore, used missing values left-censorship. Ideally, nice way test .","code":""},{"path":"/articles/testing-for-left-censorship.html","id":"strategy","dir":"Articles","previous_headings":"","what":"Strategy","title":"Testing for Left Censorship","text":"test , following (implemented test_left_censorship). feature missing one samples class samples, check non-missing entries sample’s median values. count entries sample medians successes, total number possible entries number trials binomial test, aggregating across features missing value. can perform one-tailed binomial test expectation successes greater 0.5.","code":""},{"path":"/articles/testing-for-left-censorship.html","id":"fake-data","dir":"Articles","previous_headings":"","what":"Fake Data","title":"Testing for Left Censorship","text":"start, need make fake data can evaluate test . make smallish dataset, 1000 features across 20 samples, 80% missing values due left-censored. sort initial data know can easily put missingness due left-censoring. also use log-normal distribution initially, just .","code":"set.seed(1234) n_feature = 1000 n_sample = 20 n_miss = 100 n_low = 80 test_dataset = rlnorm(n_feature, 10, 1) test_dataset = sort(test_dataset) noisy_dataset = add_uniform_noise(log(test_dataset), n_sample, 0.1) sample_medians = calculate_matrix_medians(noisy_dataset)"},{"path":"/articles/testing-for-left-censorship.html","id":"add-missingness","dir":"Articles","previous_headings":"","what":"Add Missingness","title":"Testing for Left Censorship","text":"Now can sample low high indices add missingness, well samples add . can actually visualize missingness using naniar package.","code":"low_indices = sample(seq_len(300), n_low) hi_indices = sample(seq(800, 1000), n_miss - n_low) all_indices = c(low_indices, hi_indices) sample_indices = sample(n_sample, n_miss, replace = TRUE) missing_dataset = noisy_dataset for (i_loc in seq_along(all_indices)) { missing_dataset[all_indices[i_loc], sample_indices[i_loc]] = NA } naniar::vis_miss(as.data.frame(missing_dataset))"},{"path":"/articles/testing-for-left-censorship.html","id":"test","dir":"Articles","previous_headings":"","what":"Test","title":"Testing for Left Censorship","text":"Now can actually test missingness entries.","code":"missing_test = test_left_censorship(missing_dataset) missing_test #> $values #> trials success class #> 1 1900 1520 A #> #> $binomial_test #> #> Exact binomial test #> #> data: total_success and total_trials #> number of successes = 1520, number of trials = 1900, p-value < 2.2e-16 #> alternative hypothesis: true probability of success is greater than 0.5 #> 95 percent confidence interval: #> 0.7843033 1.0000000 #> sample estimates: #> probability of success #> 0.8"},{"path":"/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Robert M Flight. Author, maintainer. Hunter NB Moseley. Author.","code":""},{"path":"/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Flight RM, Moseley HN (2024). ICIKendallTau: Calculates information-content-informed Kendall-tau. R package version 1.1.0, https://moseleybioinformaticslab.github.io/ICIKendallTau/https://github.com/moseleybioinformaticslab/ICIKendallTau/.","code":"@Manual{, title = {ICIKendallTau: Calculates information-content-informed Kendall-tau}, author = {Robert M Flight and Hunter NB Moseley}, year = {2024}, note = {R package version 1.1.0}, url = {https://moseleybioinformaticslab.github.io/ICIKendallTau/ https://github.com/moseleybioinformaticslab/ICIKendallTau/}, }"},{"path":"/index.html","id":"icikendalltau","dir":"","previous_headings":"","what":"Calculates information-content-informed Kendall-tau","title":"Calculates information-content-informed Kendall-tau","text":"can see pkgdown site .","code":""},{"path":"/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Calculates information-content-informed Kendall-tau","text":"can install current version ICIKendallTau via GitHub: can also install Windows Mac binaries using r-universe:","code":"remotes::install_github(\"MoseleyBioinformaticsLab/ICIKendallTau\") options(repos = c( moseleybioinformaticslab = 'https://moseleybioinformaticslab.r-universe.dev', CRAN = \"https://cloud.r-project.org\")) install.packages(\"ICIKendallTau\")"},{"path":"/index.html","id":"problem","dir":"","previous_headings":"","what":"Problem","title":"Calculates information-content-informed Kendall-tau","text":"handle missing data (.e. NA’s) calculating correlation two variables. However, whether observation present missing semi-quantitative information many analytical measurements sensitivity limits. .e. many cases, missing observations “missing--random”, “missing---random” due falling detection limit. cases, NA informative. Therefore, analytical measurements (gene expression, proteomics, metabolomics), missing measurements included, contribute correlation. want read solve problem, see package vignette.","code":""},{"path":"/index.html","id":"package-functions","dir":"","previous_headings":"","what":"Package Functions","title":"Calculates information-content-informed Kendall-tau","text":"functions implement include: option perspective control NA values influence ties. comparing samples, likely want use perspective = \"global\". Rows features, columns samples. library(furrr) plan(multiprocess) Otherwise use single core. ’ve also included function testing missingness data comes left-censorship, test_left_censorship. walk creating example data testing vignette Testing Left Censorship.","code":""},{"path":"/index.html","id":"examples","dir":"","previous_headings":"","what":"Examples","title":"Calculates information-content-informed Kendall-tau","text":"common case large matrix independent samples (columns) measured features samples (.e. gene expression). make artificial data show correlation changes introduce missingness. Now introduce missing values low end one. just simplest thing introduce NA values bottom set.","code":"set.seed(1234) library(ICIKendallTau) s1 = sort(rnorm(1000, mean = 100, sd = 10)) s2 = s1 + 10 matrix_1 = cbind(s1, s2) r_1 = ici_kendalltau(matrix_1) r_1$cor #> s1 s2 #> s1 1 1 #> s2 1 1 s3 = s1 s3[sample(100, 50)] = NA s4 = s2 s4[sample(100, 50)] = NA matrix_2 = cbind(s3, s4) r_2 = ici_kendalltau(matrix_2) r_2$cor #> s3 s4 #> s3 1.0000000 0.9944616 #> s4 0.9944616 1.0000000"},{"path":"/index.html","id":"is-it-fast","dir":"","previous_headings":"","what":"Is It Fast?","title":"Calculates information-content-informed Kendall-tau","text":"C++ code implementation (thanks {Rcpp}!) based SciPy implementation, uses two merge sorts ranks vector, looks differences . fastest method know , complexity O(nlogn). naive way computing , explicitly examines pairs, complexity n^2. implementation compared {pcaPP::cov.fk} function, use {Rcpp} inefficient copying vectors makes 3X slower one. honestly isn’t bad. case 40,000 features, average time modern CPU 14 milliseconds. course, want use calculate Kendall-tau-b without incorporating missingness, can just fine well. also provide kt_fast function, want something treats NA values similarly stats::cor.","code":"library(microbenchmark) x = rnorm(1000) y = rnorm(1000) x2 = rnorm(40000) y2 = rnorm(40000) library(microbenchmark) microbenchmark( cor(x, y, method = \"kendall\"), ici_kt(x, y, \"global\"), ici_kt(x2, y2, \"global\"), times = 5 ) #> Unit: microseconds #> expr min lq mean median uq max neval #> cor(x, y, method = \"kendall\") 11685.244 12730.878 12860.9060 13071.630 13406.514 13410.264 5 #> ici_kt(x, y, \"global\") 263.306 268.503 332.1288 274.858 283.589 570.388 5 #> ici_kt(x2, y2, \"global\") 14110.743 14322.836 15782.6490 16053.907 16595.979 17829.780 5 k_tau = ici_kt(x, y, \"global\") all.equal(k_tau[[1]] ,cor(x, y, method = \"kendall\")) #> [1] TRUE k_tau_fast = kt_fast(x, y) k_tau_fast #> tau pvalue #> -0.003411411 0.871672260"},{"path":"/index.html","id":"parallelism","dir":"","previous_headings":"","what":"Parallelism","title":"Calculates information-content-informed Kendall-tau","text":"{future} {furrr} packages installed, also possible split set matrix comparisons across compute resources multiprocessing engine registered {future}.","code":"library(furrr) future::plan(multicore, workers = 4) r_3 = ici_kendalltau(matrix_2)"},{"path":"/index.html","id":"many-many-comparisons","dir":"","previous_headings":"","what":"Many Many Comparisons","title":"Calculates information-content-informed Kendall-tau","text":"case hundreds thousands comparisons done, result matrices can become , large, require lots memory storage. also inefficient, lower upper triangular components stored. alternative storage format data.frame, single row comparison performed. actually results stored internally, converted matrix form requested (default). keep data.frame output, add argument return_matrix=FALSE call ici_kendalltau.","code":"r_4 = ici_kendalltau(matrix_2, return_matrix = FALSE) r_4 #> $cor #> s1 s2 core raw pvalue taumax cor #> 1 s3 s4 1 0.9924359 0 0.997963 0.9944616 #> 2 s3 s3 0 1.0000000 0 1.000000 1.0000000 #> 3 s4 s4 0 1.0000000 0 1.000000 1.0000000 #> #> $run_time #> [1] 0.01747489"},{"path":"/index.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of Conduct","title":"Calculates information-content-informed Kendall-tau","text":"Please note ICIKendallTau project released Contributor Code Conduct. contributing project, agree abide terms.","code":""},{"path":"/reference/add_uniform_noise.html","id":null,"dir":"Reference","previous_headings":"","what":"Add uniform noise — add_uniform_noise","title":"Add uniform noise — add_uniform_noise","text":"Adds uniform noise values, generating replicates noise added original.","code":""},{"path":"/reference/add_uniform_noise.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Add uniform noise — add_uniform_noise","text":"","code":"add_uniform_noise(value, n_rep, sd, use_zero = FALSE)"},{"path":"/reference/add_uniform_noise.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Add uniform noise — add_uniform_noise","text":"value single vector numeric values n_rep number replicates make (numeric). Default 1. sd standard deviation data use_zero logical, returned values around zero ?","code":""},{"path":"/reference/add_uniform_noise.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Add uniform noise — add_uniform_noise","text":"numeric matrix","code":""},{"path":"/reference/calculate_matrix_medians.html","id":null,"dir":"Reference","previous_headings":"","what":"Calculate matrix medians — calculate_matrix_medians","title":"Calculate matrix medians — calculate_matrix_medians","text":"Given matrix data, calculates median value column row.","code":""},{"path":"/reference/calculate_matrix_medians.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Calculate matrix medians — calculate_matrix_medians","text":"","code":"calculate_matrix_medians(in_matrix, use = \"col\", ...)"},{"path":"/reference/calculate_matrix_medians.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Calculate matrix medians — calculate_matrix_medians","text":"in_matrix numeric matrix values use character \"col\" \"row\" defining columns rows ... extra parameters median function","code":""},{"path":"/reference/calculate_matrix_medians.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Calculate matrix medians — calculate_matrix_medians","text":"numeric","code":""},{"path":"/reference/cor_matrix_2_long_df.html","id":null,"dir":"Reference","previous_headings":"","what":"convert matrix to data.frame — cor_matrix_2_long_df","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"Given square correlation matrix, converts long data.frame, three columns.","code":""},{"path":"/reference/cor_matrix_2_long_df.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"","code":"cor_matrix_2_long_df(in_matrix)"},{"path":"/reference/cor_matrix_2_long_df.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"in_matrix correlation matrix","code":""},{"path":"/reference/cor_matrix_2_long_df.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"data.frame","code":""},{"path":"/reference/cor_matrix_2_long_df.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"convert matrix to data.frame — cor_matrix_2_long_df","text":"data.frame contains three columns: s1: first entry comparison s2: second entry comparison cor: correlation value","code":""},{"path":"/reference/disable_logging.html","id":null,"dir":"Reference","previous_headings":"","what":"turn logging off — disable_logging","title":"turn logging off — disable_logging","text":"may good reasons turn logging turned . basically tells package logger available.","code":""},{"path":"/reference/disable_logging.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"turn logging off — disable_logging","text":"","code":"disable_logging()"},{"path":"/reference/enable_logging.html","id":null,"dir":"Reference","previous_headings":"","what":"turn logging on — enable_logging","title":"turn logging on — enable_logging","text":"Choose enable logging, specific file desired.","code":""},{"path":"/reference/enable_logging.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"turn logging on — enable_logging","text":"","code":"enable_logging(log_file = NULL, memory = FALSE)"},{"path":"/reference/enable_logging.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"turn logging on — enable_logging","text":"log_file file log memory provide memory logging ? available Linux MacOS","code":""},{"path":"/reference/enable_logging.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"turn logging on — enable_logging","text":"Uses logger package hood, suggested dependencies. logging enabled nice see things starting stopping, exactly done, without needing write messages console. especially useful getting errors, really see , can add \"memory\" logging see running memory. Default log file pattern: YYYY.MM.DD.HH.MM.SS_ICIKendallTau_run.log","code":""},{"path":"/reference/ici_kendalltau.html","id":null,"dir":"Reference","previous_headings":"","what":"information-content-informed kendall tau — ici_kendalltau","title":"information-content-informed kendall tau — ici_kendalltau","text":"Given data-matrix, computes information-theoretic Kendall-tau-b samples.","code":""},{"path":"/reference/ici_kendalltau.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"information-content-informed kendall tau — ici_kendalltau","text":"","code":"ici_kendalltau( data_matrix, global_na = c(NA, Inf, 0), perspective = \"global\", scale_max = TRUE, diag_good = TRUE, include_only = NULL, check_timing = FALSE, return_matrix = TRUE )"},{"path":"/reference/ici_kendalltau.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"information-content-informed kendall tau — ici_kendalltau","text":"data_matrix matrix data.frame values, samples columns, features rows global_na numeric vector defines globally, treated NA? perspective treat missing data denominator ties, character scale_max logical, everything scaled compared maximum correlation? diag_good logical, diagonal entries reflect many entries sample \"good\"? include_only run correlations include members (vector) combinations (list data.frame) check_timing logical determine try estimate run time full dataset? (default FALSE) return_matrix logical, data.frame matrix result returned?","code":""},{"path":"/reference/ici_kendalltau.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"information-content-informed kendall tau — ici_kendalltau","text":"list cor, raw, pval, taumax","code":""},{"path":"/reference/ici_kendalltau.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"information-content-informed kendall tau — ici_kendalltau","text":"details, see vignette vignette(\"ici-kendalltau\", package = \"ICIKendallTau\")) default global_na includes values data replace NA Kendall-tau calculation. default global_na = c(NA, Inf, 0). want replace something 0, example, might use global_na = c(NA, Inf, -2), values -2 replaced instead 0. check_timing = TRUE, 5 random pairwise comparisons run generate timings single core, estimates long full set take calculated. data returned data.frame, low side, provide good idea long data take. Returned list containing matrices : cor: scaled correlations raw: raw kendall-tau correlations pval: p-values taumax: theoretical maximum kendall-tau value possible Eventually, plan provide two parameters replacing values, feature_na feature specific NA values sample_na sample specific NA values. want know missing values data possibly due left-censorship, recommend testing hypothesis test_left_censorship() first.","code":""},{"path":[]},{"path":"/reference/ici_kendalltau.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"information-content-informed kendall tau — ici_kendalltau","text":"","code":"if (FALSE) { # not run set.seed(1234) s1 = sort(rnorm(1000, mean = 100, sd = 10)) s2 = s1 + 10 matrix_1 = cbind(s1, s2) r_1 = ici_kendalltau(matrix_1) r_1$cor # s1 s2 # s1 1 1 # s2 1 1 names(r_1) # \"cor\", \"raw\", \"pval\", \"taumax\", \"keep\", \"run_time\" s3 = s1 s3[sample(100, 50)] = NA s4 = s2 s4[sample(100, 50)] = NA matrix_2 = cbind(s3, s4) r_2 = ici_kendalltau(matrix_2) r_2$cor # s3 s4 # s3 1.0000000 0.9944616 # s4 0.9944616 1.0000000 # using include_only set.seed(1234) x = t(matrix(rnorm(5000), nrow = 100, ncol = 50)) colnames(x) = paste0(\"s\", seq(1, nrow(x))) # only calculate correlations of other columns with \"s1\" include_s1 = \"s1\" s1_only = ici_kendalltau(x, include_only = include_s1) # include s1 and s3 things both include_s1s3 = c(\"s1\", \"s3\") s1s3_only = ici_kendalltau(x, include_only = include_s1s3) # only specify certain pairs either as a list include_pairs = list(g1 = \"s1\", g2 = c(\"s2\", \"s3\")) s1_other = ici_kendalltau(x, include_only = include_pairs) # or a data.frame include_df = as.data.frame(list(g1 = \"s1\", g2 = c(\"s2\", \"s3\"))) s1_df = ici_kendalltau(x, include_only = include_df) }"},{"path":"/reference/ici_kendalltau_ref.html","id":null,"dir":"Reference","previous_headings":"","what":"information-content-informed kendall tau — ici_kendalltau_ref","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"Given data-matrix, computes information-content-informed (ICI) Kendall-tau-b samples.","code":""},{"path":"/reference/ici_kendalltau_ref.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"","code":"ici_kendalltau_ref( data_matrix, global_na = c(NA, Inf, 0), zero_value = 0, perspective = \"global\", scale_max = TRUE, diag_good = TRUE, progress = FALSE )"},{"path":"/reference/ici_kendalltau_ref.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"data_matrix samples columns, features rows global_na values treated missing (NA)? zero_value actual zero value? perspective treat missing data denominator ties, see details scale_max everything scaled compared maximum correlation? diag_good diagonal entries reflect many entries sample \"good\"? progress progress displayed.","code":""},{"path":"/reference/ici_kendalltau_ref.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"numeric","code":""},{"path":"/reference/ici_kendalltau_ref.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"information-content-informed kendall tau — ici_kendalltau_ref","text":"details, see ICI-Kendall-tau vignette: vignette(\"ici-kendalltau\", package = \"ICIKendallTau\")","code":""},{"path":"/reference/ici_kt.html","id":null,"dir":"Reference","previous_headings":"","what":"Calculates ici-kendall-tau — ici_kt","title":"Calculates ici-kendall-tau — ici_kt","text":"Calculates ici-kendall-tau","code":""},{"path":"/reference/ici_kt.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Calculates ici-kendall-tau — ici_kt","text":"","code":"ici_kt( x, y, perspective = \"local\", alternative = \"two.sided\", continuity = FALSE, output = \"simple\" )"},{"path":"/reference/ici_kt.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Calculates ici-kendall-tau — ici_kt","text":"x numeric vector y numeric vector perspective consider \"local\" \"global\" perspective? alternative alternative p-value test? continuity logical: true, continuity correction used output used control reporting values debugging","code":""},{"path":"/reference/ici_kt.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Calculates ici-kendall-tau — ici_kt","text":"kendall tau correlation, p-value, max-correlation","code":""},{"path":"/reference/ici_kt.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Calculates ici-kendall-tau — ici_kt","text":"Calculates information-content-informed Kendall-tau correlation measure. correlation based concordant discordant ranked pairs, like Kendall-tau, also includes missing values (NA). Missing values assumed primarily due lack detection due instrumental sensitivity, therefore encode information. details see ICI-Kendall-tau vignette: browseVignettes(\"ICIKendallTau\")","code":""},{"path":"/reference/ici_kt.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Calculates ici-kendall-tau — ici_kt","text":"","code":"x = sort(rnorm(100)) y = x + 1 y2 = y y2[1:10] = NA ici_kt(x, y) #> tau pvalue tau_max #> 1.000000e+00 3.480281e-49 1.000000e+00 ici_kt(x, y2, \"global\") #> tau pvalue tau_max #> 9.954442e-01 2.228308e-48 9.954442e-01 ici_kt(x, y2) #> tau pvalue tau_max #> 9.954442e-01 2.228308e-48 9.954442e-01"},{"path":"/reference/kt_fast.html","id":null,"dir":"Reference","previous_headings":"","what":"fast kendall tau — kt_fast","title":"fast kendall tau — kt_fast","text":"Uses underlying c++ implementation ici_kt provide fast version Kendall-tau correlation.","code":""},{"path":"/reference/kt_fast.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"fast kendall tau — kt_fast","text":"","code":"kt_fast(x, y = NULL, use = \"everything\", return_matrix = TRUE)"},{"path":"/reference/kt_fast.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"fast kendall tau — kt_fast","text":"x numeric vector, matrix, data frame. y NULL (default) vector. use optional character string giving method computing correlations presence missing values. must (abbreviation ) one strings \"everything\", \".obs\", \"complete.obs\", \"pairwise.complete.obs\". return_matrix matrices values returned, long data.frame","code":""},{"path":"/reference/kt_fast.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"fast kendall tau — kt_fast","text":"named vector list matrices.","code":""},{"path":"/reference/kt_fast.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"fast kendall tau — kt_fast","text":"Although interface mostly identical built-stats::cor() method, differences. providing x y, assumed single vectors. NA values present, function error, either remove return NA, depending option. \"na..complete\" valid option use. named vector named list matrices returned, tau pvalue values.","code":""},{"path":"/reference/log_memory.html","id":null,"dir":"Reference","previous_headings":"","what":"log memory usage — log_memory","title":"log memory usage — log_memory","text":"Logs amount memory used log file available, generating warnings amount RAM hits zero.","code":""},{"path":"/reference/log_memory.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"log memory usage — log_memory","text":"","code":"log_memory()"},{"path":"/reference/log_message.html","id":null,"dir":"Reference","previous_headings":"","what":"log messages — log_message","title":"log messages — log_message","text":"log_appender available, logs given message info level.","code":""},{"path":"/reference/log_message.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"log messages — log_message","text":"","code":"log_message(message_string)"},{"path":"/reference/log_message.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"log messages — log_message","text":"message_string string put message","code":""},{"path":"/reference/long_df_2_cor_matrix.html","id":null,"dir":"Reference","previous_headings":"","what":"convert data.frame to matrix — long_df_2_cor_matrix","title":"convert data.frame to matrix — long_df_2_cor_matrix","text":"Given long data.frame, converts possibly square correlation matrix","code":""},{"path":"/reference/long_df_2_cor_matrix.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"convert data.frame to matrix — long_df_2_cor_matrix","text":"","code":"long_df_2_cor_matrix(long_df, is_square = TRUE)"},{"path":"/reference/long_df_2_cor_matrix.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"convert data.frame to matrix — long_df_2_cor_matrix","text":"long_df long data.frame is_square square matrix?","code":""},{"path":"/reference/long_df_2_cor_matrix.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"convert data.frame to matrix — long_df_2_cor_matrix","text":"matrix","code":""},{"path":"/reference/missing_dataset.html","id":null,"dir":"Reference","previous_headings":"","what":"Example Dataset With Missingness — missing_dataset","title":"Example Dataset With Missingness — missing_dataset","text":"example dataset missingness left-censorship","code":""},{"path":"/reference/missing_dataset.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Example Dataset With Missingness — missing_dataset","text":"","code":"missing_dataset"},{"path":[]},{"path":"/reference/missing_dataset.html","id":"missing-dataset","dir":"Reference","previous_headings":"","what":"missing_dataset","title":"Example Dataset With Missingness — missing_dataset","text":"matrix 1000 rows 20 columns, rows features columns samples.","code":""},{"path":"/reference/missing_dataset.html","id":"source","dir":"Reference","previous_headings":"","what":"Source","title":"Example Dataset With Missingness — missing_dataset","text":"Robert M Flight","code":""},{"path":"/reference/pairwise_completeness.html","id":null,"dir":"Reference","previous_headings":"","what":"pairwise completeness — pairwise_completeness","title":"pairwise completeness — pairwise_completeness","text":"Calculates completeness two samples using \"\", entry missing either X \"\" Y.","code":""},{"path":"/reference/pairwise_completeness.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"pairwise completeness — pairwise_completeness","text":"","code":"pairwise_completeness( data_matrix, global_na = c(NA, Inf, 0), include_only = NULL, return_matrix = TRUE )"},{"path":"/reference/pairwise_completeness.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"pairwise completeness — pairwise_completeness","text":"data_matrix samples columns, features rows global_na globally, treated NA? include_only certain comparisons ? return_matrix matrix data.frame returned?","code":""},{"path":"/reference/pairwise_completeness.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"pairwise completeness — pairwise_completeness","text":"matrix degree completeness","code":""},{"path":[]},{"path":"/reference/show_progress.html","id":null,"dir":"Reference","previous_headings":"","what":"turn progress on off — show_progress","title":"turn progress on off — show_progress","text":"Allow user turn progress messages console . Default provide messages console.","code":""},{"path":"/reference/show_progress.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"turn progress on off — show_progress","text":"","code":"show_progress(progress = TRUE)"},{"path":"/reference/show_progress.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"turn progress on off — show_progress","text":"progress logical ","code":""},{"path":"/reference/test_left_censorship.html","id":null,"dir":"Reference","previous_headings":"","what":"Test for left censorship — test_left_censorship","title":"Test for left censorship — test_left_censorship","text":"binomial test check likely cause missing values due values limit detection, coming left-censored distribution.","code":""},{"path":"/reference/test_left_censorship.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Test for left censorship — test_left_censorship","text":"","code":"test_left_censorship(in_data, sample_classes = NULL, global_na = c(NA, Inf, 0))"},{"path":"/reference/test_left_censorship.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Test for left censorship — test_left_censorship","text":"in_data matrix data.frame numeric data sample_classes samples class global_na represents zero missing?","code":""},{"path":"/reference/test_left_censorship.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Test for left censorship — test_left_censorship","text":"data.frame trials / successes, binom.test result","code":""},{"path":"/reference/test_left_censorship.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Test for left censorship — test_left_censorship","text":"feature missing group samples, save possibility test. sample, calculate median value missing values removed. feature missing value, test whether remaining non-missing values sample median samples feature non-missing. binomial test considers total number features instances (minus missing values) number trials, number features sample medians number successes. bit detail vignette: vignette(\"testing--left-censorship\", package = \"ICIKendallTau\")","code":""},{"path":[]},{"path":"/reference/test_left_censorship.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Test for left censorship — test_left_censorship","text":"","code":"# this example has 80% missing due to left-censorship data(missing_dataset) missingness = test_left_censorship(missing_dataset) missingness$values #> trials success class #> 1 1900 1520 A missingness$binomial_test #> #> \tExact binomial test #> #> data: total_success and total_trials #> number of successes = 1520, number of trials = 1900, p-value < 2.2e-16 #> alternative hypothesis: true probability of success is greater than 0.5 #> 95 percent confidence interval: #> 0.7843033 1.0000000 #> sample estimates: #> probability of success #> 0.8 #>"},{"path":"/news/index.html","id":"icikendalltau-110","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 1.1.0","title":"ICIKendallTau 1.1.0","text":"adds function test_left_censorship verify ici_kendalltau appropriate use data .","code":""},{"path":"/news/index.html","id":"icikendalltau-100","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 1.0.0","title":"ICIKendallTau 1.0.0","text":"Calculates correlation columns matrix, rows.","code":""},{"path":"/news/index.html","id":"icikendalltau-0320","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.3.20","title":"ICIKendallTau 0.3.20","text":"kt_fast now uses data.frame format output ici_kendalltau, returns matrix default. data.frame useful large amounts comparisons run.","code":""},{"path":"/news/index.html","id":"icikendalltau-030","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.3.0","title":"ICIKendallTau 0.3.0","text":"Handling parallel execution differently avoid really large matrix issues core. Introduces return_matrix parameter ici_kendalltau allows return results form data.frame instead lists matrices.","code":""},{"path":"/news/index.html","id":"icikendalltau-0210","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.2.10","title":"ICIKendallTau 0.2.10","text":"Provide kt_fast function handles missing NA values similarly stats::cor function, uses ici_kt fast function underneath.","code":""},{"path":"/news/index.html","id":"icikendalltau-028","dir":"Changelog","previous_headings":"","what":"ICIKendalltau 0.2.8","title":"ICIKendalltau 0.2.8","text":"Made error outputs length default output containing NA. Check case one variables ici_kt identical arguments, warns user returns NA.","code":""},{"path":"/news/index.html","id":"icikendalltau-021","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.2.1","title":"ICIKendallTau 0.2.1","text":"Added new argument include_only ici_kendalltau allows user define pairwise correlations actually .","code":""},{"path":"/news/index.html","id":"icikendalltau-0117","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.1.17","title":"ICIKendallTau 0.1.17","text":"switched theme. updated installation instructions use r-universe.","code":""},{"path":"/news/index.html","id":"icikendalltau-0116","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.1.16","title":"ICIKendallTau 0.1.16","text":"updating documentation examples","code":""},{"path":"/news/index.html","id":"icikendalltau-014","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.1.4","title":"ICIKendallTau 0.1.4","text":"Switched pairwise_completeness also use global_na parameter. Oh yes, function pairwise_completeness enable scaling completeness two samples.","code":""},{"path":"/news/index.html","id":"icikendalltau-012","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.1.2","title":"ICIKendallTau 0.1.2","text":"Updated API use single variable, global_na defines values set NA correlation calculation. big API change, bumped version 0.1.","code":""},{"path":"/news/index.html","id":"icikendalltau-006","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.6","title":"ICIKendallTau 0.0.6","text":"Fixing bug 55,000 elements vector, match overflows 32 bit 64 bit, results make sense.","code":""},{"path":"/news/index.html","id":"icikendalltau-005","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.5","title":"ICIKendallTau 0.0.5","text":"Fixed bug instead returning two element vector, returned zero length value. probably happened one entries contained NA values, tried pass “vectors” less two entries.","code":""},{"path":"/news/index.html","id":"icikendalltau-004","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.4","title":"ICIKendallTau 0.0.4","text":"Fixing things came R CMD check documentation. good now (hope).","code":""},{"path":"/news/index.html","id":"icikendalltau-003","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.3","title":"ICIKendallTau 0.0.3","text":"Added tests! Removed bunch code wasn’t necessary using incorrect formula’s, correct version ici_kt_pairs function reference purposes.","code":""},{"path":"/news/index.html","id":"icikendalltau-002","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.2","title":"ICIKendallTau 0.0.2","text":"Fixed issue warning issued {furrr} installed.","code":""},{"path":"/news/index.html","id":"icikendalltau-001","dir":"Changelog","previous_headings":"","what":"ICIKendallTau 0.0.1","title":"ICIKendallTau 0.0.1","text":"First release. ’s tested used rather thoroughly , ’d say ’s still rather alpha. Even though use time . Added NEWS.md file track changes package.","code":""}] diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 03df9a5..e9b2467 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -18,6 +18,9 @@ /articles/index.html + + /articles/testing-for-left-censorship.html + /authors.html @@ -27,6 +30,12 @@ /news/index.html + + /reference/add_uniform_noise.html + + + /reference/calculate_matrix_medians.html + /reference/cor_matrix_2_long_df.html @@ -60,6 +69,9 @@ /reference/long_df_2_cor_matrix.html + + /reference/missing_dataset.html + /reference/pairwise_completeness.html @@ -72,4 +84,7 @@ /reference/show_progress.html + + /reference/test_left_censorship.html + diff --git a/man/ici_kendalltau.Rd b/man/ici_kendalltau.Rd index eaf584d..938e5fa 100644 --- a/man/ici_kendalltau.Rd +++ b/man/ici_kendalltau.Rd @@ -40,9 +40,7 @@ Given a data-matrix, computes the information-theoretic Kendall-tau-b between all samples. } \details{ -For more details, see the ICI-Kendall-tau vignette - -\code{browseVignettes("ICIKendallTau")} +For more details, see the vignette \verb{vignette("ici-kendalltau", package = "ICIKendallTau"))} The default for \code{global_na} includes what values in the data to replace with NA for the Kendall-tau calculation. By default these are \code{global_na = c(NA, Inf, 0)}. If you want to replace something other than 0, for example, you might use \code{global_na = c(NA, Inf, -2)}, and all values of -2 will be replaced instead of 0. @@ -57,6 +55,10 @@ Returned is a list containing matrices with: } Eventually, we plan to provide two more parameters for replacing values, \code{feature_na} for feature specific NA values and \code{sample_na} for sample specific NA values. + +If you want to know if the missing values in your data are possibly due to +left-censorship, we recommend testing that hypothesis with \code{\link[=test_left_censorship]{test_left_censorship()}} +first. } \examples{ \dontrun{ @@ -112,3 +114,6 @@ s1_df = ici_kendalltau(x, include_only = include_df) } } +\seealso{ +\code{\link[=test_left_censorship]{test_left_censorship()}} \code{\link[=pairwise_completeness]{pairwise_completeness()}} \code{\link[=kt_fast]{kt_fast()}} +} diff --git a/man/kt_fast.Rd b/man/kt_fast.Rd index 192ee42..925a9f7 100644 --- a/man/kt_fast.Rd +++ b/man/kt_fast.Rd @@ -23,8 +23,8 @@ Uses the underlying c++ implementation of \code{ici_kt} to provide a fast versio of Kendall-tau correlation. } \details{ -Although the interface is \emph{mostly} identical to the built-in \code{stats::cor} method, -there are some differences. +Although the interface is \emph{mostly} identical to the built-in +\code{\link[stats:cor]{stats::cor()}} method, there are some differences. \itemize{ \item if providing both \code{x} and \code{y}, it is assumed they are both single vectors. diff --git a/man/pairwise_completeness.Rd b/man/pairwise_completeness.Rd index eaf7926..1bb3072 100644 --- a/man/pairwise_completeness.Rd +++ b/man/pairwise_completeness.Rd @@ -27,3 +27,6 @@ matrix of degree of completeness Calculates the completeness between any two samples using "or", is an entry missing in either X "or" Y. } +\seealso{ +\code{\link[=ici_kendalltau]{ici_kendalltau()}} +} diff --git a/man/test_left_censorship.Rd b/man/test_left_censorship.Rd index 6a72980..d6d87da 100644 --- a/man/test_left_censorship.Rd +++ b/man/test_left_censorship.Rd @@ -4,7 +4,7 @@ \alias{test_left_censorship} \title{Test for left censorship} \usage{ -test_left_censorship(in_data, sample_classes = NULL, global_na = c(0, NA)) +test_left_censorship(in_data, sample_classes = NULL, global_na = c(NA, Inf, 0)) } \arguments{ \item{in_data}{matrix or data.frame of numeric data} @@ -29,6 +29,8 @@ non-missing values are below the sample median for those samples where the feature is non-missing. A binomial test considers the total number of features instances (minus missing values) as the number of trials, and the number of of features below the sample medians as the number of successes. + +There is a bit more detail in the vignette: \code{vignette("testing-for-left-censorship", package = "ICIKendallTau")} } \examples{ # this example has 80\% missing due to left-censorship @@ -39,5 +41,5 @@ missingness$binomial_test } \seealso{ -\link{vignette("Testing for Left Censorship", package = "ICIKendallTau")} +\code{\link[=ici_kendalltau]{ici_kendalltau()}} } diff --git a/vignettes/ici-kendalltau.Rmd b/vignettes/ici-kendalltau.Rmd index 8238c31..0901ba4 100644 --- a/vignettes/ici-kendalltau.Rmd +++ b/vignettes/ici-kendalltau.Rmd @@ -108,6 +108,8 @@ The functions that implement this include: * `plan(multiprocess)` * Otherwise will only use a single core. +We've also included a function for testing if the missingness in your data comes from left-censorship, `test_left_censorship`. We walk through creating example data and testing it in the vignette [Testing for Left Censorship](vignette("Testing for Left Censorship", package = "ICIKendallTau")). + ## Implementation It turns out, if we think about it really hard, all that is truly necessary is to replace missing values in each vector with a value smaller than the minimum value in each one. @@ -172,7 +174,7 @@ r_2 = ici_kendalltau(matrix_1) In the case of hundreds of thousands of comparisons to be done, the result matrices can become very, very large, and require lots of memory for storage. They are also inefficient, as both the lower and upper triangular components are stored. An alternative storage format is as a `data.frame`, where there is a single row for each comparison performed. -This is actually how the results are stored internally, and then they are converted to a matrix form if requested (the default).s +This is actually how the results are stored internally, and then they are converted to a matrix form if requested (the default). To keep the `data.frame` output, add the argument `return_matrix=FALSE` to the call of `ici_kendalltau`. ```{r} diff --git a/vignettes/testing-for-left-censorship.Rmd b/vignettes/testing-for-left-censorship.Rmd new file mode 100644 index 0000000..67557d9 --- /dev/null +++ b/vignettes/testing-for-left-censorship.Rmd @@ -0,0 +1,91 @@ +--- +title: "Testing for Left Censorship" +output: rmarkdown::html_vignette +author: "Robert M Flight and Hunter NB Moseley" +vignette: > + %\VignetteIndexEntry{Testing for Left Censorship} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} + \usepackage[utf8]{naniar} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library(ICIKendallTau) +``` + +## Why? + +{ICIKendallTau} has a very specific assumption, that the missing values are **largely** due to being below the limit of detection, or the result of left-censorship. +Therefore, it should only be used **if** the missing values are from left-censorship. +Ideally, it would be nice to have a way to test for it. + +## Strategy + +To test this, we do the following (implemented in `test_left_censorship`). +For any feature that is missing in one or more samples in a class of samples, we check if the non-missing entries are below their sample's median values. +We count all of the entries below sample medians as successes, and the total number of possible entries as the number of trials in a binomial test, aggregating across all features that had a missing value. +We can then perform a one-tailed binomial test with the expectation that the successes are greater than 0.5. + +## Fake Data + +To start, we need to make some fake data that we can evaluate the test on. +We will make a smallish dataset, with 1000 features across 20 samples, and we will have 80% of the missing values be due to being left-censored. + +We sort the initial data so we know where we can easily put missingness due to left-censoring. +We also use a log-normal distribution initially, just because. + +```{r} +#| label: create-fake-data +set.seed(1234) +n_feature = 1000 +n_sample = 20 +n_miss = 100 +n_low = 80 +test_dataset = rlnorm(n_feature, 10, 1) +test_dataset = sort(test_dataset) + +noisy_dataset = add_uniform_noise(log(test_dataset), n_sample, 0.1) +sample_medians = calculate_matrix_medians(noisy_dataset) +``` + +## Add Missingness + +Now we can sample some low and high indices to add our missingness, as well as some samples to add them to. + +```{r} +#| label: add-missingness +low_indices = sample(seq_len(300), n_low) +hi_indices = sample(seq(800, 1000), n_miss - n_low) + +all_indices = c(low_indices, hi_indices) +sample_indices = sample(n_sample, n_miss, replace = TRUE) + +missing_dataset = noisy_dataset +for (i_loc in seq_along(all_indices)) { + missing_dataset[all_indices[i_loc], sample_indices[i_loc]] = NA +} +``` + +We can actually visualize the missingness using the `naniar` package. + +```{r} +#| label: examine-missingness +naniar::vis_miss(as.data.frame(missing_dataset)) +``` + +## Test + +Now we can actually test the missingness entries. + +```{r} +#| label: test-missingness +missing_test = test_left_censorship(missing_dataset) +missing_test +```