diff --git a/.gitignore b/.gitignore index 145eac0..190e120 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,11 @@ .RData .Ruserdata .Rproj.user +.lintr vignettes/figures *.pdf -*.html \ No newline at end of file +*.html + +*.code-workspace +.vscode diff --git a/R/create.clone.genome.distribution.plot.R b/R/create.clone.genome.distribution.plot.R index dbc52fe..a3a72fd 100644 --- a/R/create.clone.genome.distribution.plot.R +++ b/R/create.clone.genome.distribution.plot.R @@ -12,8 +12,14 @@ create.clone.genome.distribution.plot <- function( ) { # Preprocess ---------------------------------------------------------------------------------- - if (!all(c('chr', 'pos', 'clone.id') %in% names(snv.df))) { - stop('snv.df does not contain at least one of chr, pos or clone.id columns') + required.cols <- c('chr', 'pos', 'clone.id'); + missing.cols <- required.cols[!(required.cols %in% names(snv.df))]; + if (length(missing.cols) != 0) { + stop(paste0( + 'snv.df must contain the columns ', + oxford.comma.vector.concat(required.cols), + '; snv.df is missing ', + oxford.comma.vector.concat(missing.cols, paste(required.cols, collapse = ', ')), '.')); } if (is.null(clone.order)) { clone.order <- sort(unique(snv.df$clone.id)); diff --git a/R/data.frame.to.array.R b/R/data.frame.to.array.R index 2f31f7d..48374ed 100644 --- a/R/data.frame.to.array.R +++ b/R/data.frame.to.array.R @@ -5,8 +5,14 @@ data.frame.to.array <- function( y.axis = 'ID' ) { - if (is.null(DF[[x.axis]]) | is.null(DF[[value]]) | is.null(DF[[y.axis]])) { - stop(paste('Dataframe does not contain one of the columns:', value, x.axis, y.axis)); + required.cols <- c(value, x.axis, y.axis); + missing.cols <- required.cols[!(required.cols %in% names(DF))]; + if (length(missing.cols) != 0) { + stop(paste0( + 'Dataframe must contain the columns: ', + oxford.comma.vector.concat(required.cols), + '; Dataframe is missing ', + oxford.comma.vector.concat(missing.cols, paste(required.cols, collapse = ', ')), '.')); } arr <- reshape( data = DF[, c(x.axis, y.axis, value)], diff --git a/R/utility.R b/R/utility.R index e780345..695d290 100644 --- a/R/utility.R +++ b/R/utility.R @@ -62,3 +62,19 @@ get.encoded.distance <- function(points) { return(encoded.distances); } + + +oxford.comma.vector.concat <- function(vec, empty.value = '', flatten.empty.value = TRUE) { + if (length(vec) == 0) { + if (flatten.empty.value) { + oxford.comma.vector.concat(empty.value, flatten.empty.value = FALSE) + } else { + empty.value; + } + } else if (length(vec) == 1) { + paste(vec, collapse = ', '); + } else { + sep <- if (length(vec) > 2) ', and ' else ' and '; + paste(paste(head(vec, -1), collapse = ', '), tail(vec, 1), sep = sep); + } + } diff --git a/tests/testthat/test-create.clone.genome.distribution.plot.R b/tests/testthat/test-create.clone.genome.distribution.plot.R new file mode 100644 index 0000000..cd98d1f --- /dev/null +++ b/tests/testthat/test-create.clone.genome.distribution.plot.R @@ -0,0 +1,22 @@ +test_that('create.clone.genome.distribution.plot enforces data.frame columns', { + snv.df <- data.frame(); + expect_error( + create.clone.genome.distribution.plot(snv.df), + 'must contain the columns chr, pos, and clone.id; snv.df is missing chr, pos, and clone.id.' + ); + snv.df <- data.frame(chr = 1); + expect_error( + create.clone.genome.distribution.plot(snv.df), + 'must contain the columns chr, pos, and clone.id; snv.df is missing pos and clone.id.' + ); + snv.df <- data.frame(chr = 1, pos = 1); + expect_error( + create.clone.genome.distribution.plot(snv.df), + 'must contain the columns chr, pos, and clone.id; snv.df is missing clone.id.' + ); + snv.df <- data.frame(clone.id = 1); + expect_error( + create.clone.genome.distribution.plot(snv.df), + 'must contain the columns chr, pos, and clone.id; snv.df is missing chr and pos.' + ); +}); diff --git a/tests/testthat/test-data.frame.to.array.R b/tests/testthat/test-data.frame.to.array.R new file mode 100644 index 0000000..9a11c07 --- /dev/null +++ b/tests/testthat/test-data.frame.to.array.R @@ -0,0 +1,22 @@ +test_that('data.frame.to.array enforces data.frame columns', { + DF <- data.frame(); + expect_error( + data.frame.to.array(DF), + 'Dataframe must contain the columns: CCF, SNV.id, and ID; Dataframe is missing CCF, SNV.id, and ID.' + ); + DF <- data.frame(CCF = 1); + expect_error( + data.frame.to.array(DF), + 'Dataframe must contain the columns: CCF, SNV.id, and ID; Dataframe is missing SNV.id and ID.' + ); + DF <- data.frame(CCF = 1, SNV.id = 1); + expect_error( + data.frame.to.array(DF), + 'Dataframe must contain the columns: CCF, SNV.id, and ID; Dataframe is missing ID.' + ); + DF <- data.frame(SNV.id = 1); + expect_error( + data.frame.to.array(DF), + 'Dataframe must contain the columns: CCF, SNV.id, and ID; Dataframe is missing CCF and ID.' + ); +}); diff --git a/tests/testthat/test-utility.R b/tests/testthat/test-utility.R index aeb18c7..76284f1 100644 --- a/tests/testthat/test-utility.R +++ b/tests/testthat/test-utility.R @@ -76,3 +76,67 @@ test_that( expect_equal(order(result), expected.order); }); + +test_that( + 'oxford.comma.vector.concat returns `empty.value` when input is empty', { + vec <- NULL; + expect_equal(oxford.comma.vector.concat(vec), ''); + expect_equal(oxford.comma.vector.concat(vec, 'default'), 'default'); + vec <- c(NULL); + expect_equal(oxford.comma.vector.concat(vec), ''); + expect_equal(oxford.comma.vector.concat(vec, 'default'), 'default'); + vec <- c(NULL, NULL); + expect_equal(oxford.comma.vector.concat(vec), ''); + expect_equal(oxford.comma.vector.concat(vec, 'default'), 'default'); + vec <- c(); + expect_equal(oxford.comma.vector.concat(vec), ''); + expect_equal(oxford.comma.vector.concat(vec, 'default'), 'default'); + }); + +test_that( + 'oxford.comma.vector.concat returns `empty.value` in correct format when input is empty', { + vec <- NULL; + expect_equal(oxford.comma.vector.concat(vec, flatten.empty.value = FALSE), ''); + expect_equal(oxford.comma.vector.concat(vec, 'default', flatten.empty.value = FALSE), 'default'); + vec <- c(NULL); + expect_equal(oxford.comma.vector.concat(vec, flatten.empty.value = FALSE), ''); + expect_equal(oxford.comma.vector.concat(vec, 'default', flatten.empty.value = FALSE), 'default'); + vec <- c(NULL, NULL); + expect_equal(oxford.comma.vector.concat(vec, flatten.empty.value = FALSE), ''); + expect_equal(oxford.comma.vector.concat(vec, 'default', flatten.empty.value = FALSE), 'default'); + vec <- c(); + expect_equal(oxford.comma.vector.concat(vec, flatten.empty.value = FALSE), ''); + expect_equal(oxford.comma.vector.concat(vec, 'default', flatten.empty.value = FALSE), 'default'); + + vec <- c(); + vec.default <- NULL; + expect_null(oxford.comma.vector.concat(vec, vec.default, flatten.empty.value = FALSE)); + vec <- c(); + vec.default <- c(1, 2, 3); + expect_equal(oxford.comma.vector.concat(vec, vec.default), '1, 2, and 3'); + expect_equal(oxford.comma.vector.concat(vec, vec.default, flatten.empty.value = FALSE), c(1, 2, 3)); + }); + +test_that( + 'oxford.comma.vector.concat returns grammatically correct oxford comma', { + vec <- c(1); + expect_equal(oxford.comma.vector.concat(vec), '1'); + vec <- c(1, 2); + expect_equal(oxford.comma.vector.concat(vec), '1 and 2'); + vec <- c(1, 2, 3); + expect_equal(oxford.comma.vector.concat(vec), '1, 2, and 3'); + vec <- c(1, 2, 3, 4); + expect_equal(oxford.comma.vector.concat(vec), '1, 2, 3, and 4'); + }); + +test_that( + 'oxford.comma.vector.concat returns grammatically correct oxford comma for flattened default value', { + vec.default <- c(1); + expect_equal(oxford.comma.vector.concat(NULL, vec.default), '1'); + vec.default <- c(1, 2); + expect_equal(oxford.comma.vector.concat(NULL, vec.default), '1 and 2'); + vec.default <- c(1, 2, 3); + expect_equal(oxford.comma.vector.concat(NULL, vec.default), '1, 2, and 3'); + vec.default <- c(1, 2, 3, 4); + expect_equal(oxford.comma.vector.concat(NULL, vec.default), '1, 2, 3, and 4'); + });