From c798f978e26f7819e08703aa85ca46606e9bac1b Mon Sep 17 00:00:00 2001 From: Nic Date: Tue, 13 Nov 2018 08:12:07 +0000 Subject: [PATCH 1/5] Fix #101 - throw an error if the x argument supplied to vis_dat is not a data.frame --- R/vis-dat.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/R/vis-dat.R b/R/vis-dat.R index d9103ab..6193f94 100644 --- a/R/vis-dat.R +++ b/R/vis-dat.R @@ -64,6 +64,10 @@ vis_dat <- function(x, warn_large_data = TRUE, large_data_size = 900000) { + if(!("data.frame" %in% class(x))){ + stop("x must be a data.frame object") + } + # add warning for large data if (ncol(x) * nrow(x) > large_data_size && warn_large_data){ stop("Data exceeds recommended size for visualisation, please consider From 40519e83918fe96695173972d63354e905042cd1 Mon Sep 17 00:00:00 2001 From: Nic Date: Wed, 14 Nov 2018 23:08:24 +0000 Subject: [PATCH 2/5] Add test for vis_dat when used on non data.frame object --- tests/testthat/test-vis-dat.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/testthat/test-vis-dat.R b/tests/testthat/test-vis-dat.R index 6c5dfa6..048619c 100644 --- a/tests/testthat/test-vis-dat.R +++ b/tests/testthat/test-vis-dat.R @@ -31,3 +31,7 @@ test_that("vis_dat fails when the wrong palette is provided",{ cat(sprintf("FreeType version: %s\n", ver)) expect_error(vis_dat(typical_data, palette = "wat")) }) + +test_that("vis_dat fails when an object of the wrong class is provided", { + expect_error(vis_dat(AirPassengers)) +}) From a0415b3c7c9528aefae54b31e8e845b087c920dd Mon Sep 17 00:00:00 2001 From: Nic Date: Wed, 14 Nov 2018 23:09:12 +0000 Subject: [PATCH 3/5] Use more informative error message and inherits() to test for class of vis_dat x parameter --- R/vis-dat.R | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/R/vis-dat.R b/R/vis-dat.R index 6193f94..1909dd6 100644 --- a/R/vis-dat.R +++ b/R/vis-dat.R @@ -64,8 +64,10 @@ vis_dat <- function(x, warn_large_data = TRUE, large_data_size = 900000) { - if(!("data.frame" %in% class(x))){ - stop("x must be a data.frame object") + # throw error if x not data.frame + if(!(inherits(x, "data.frame"))){ + stop("Oops - vis_dat requires x to be an object of class data.frame but the object you've provided me with is of class(es): ", + paste(class(x), collapse = ", ")) } # add warning for large data From 874473d89dc2f98ee18453fdd1ec4d9a600585db Mon Sep 17 00:00:00 2001 From: Nic Date: Fri, 16 Nov 2018 09:02:05 +0000 Subject: [PATCH 4/5] #101 - Rephrase vis_dat error message --- R/vis-dat.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/vis-dat.R b/R/vis-dat.R index 1909dd6..9c7361c 100644 --- a/R/vis-dat.R +++ b/R/vis-dat.R @@ -66,7 +66,7 @@ vis_dat <- function(x, # throw error if x not data.frame if(!(inherits(x, "data.frame"))){ - stop("Oops - vis_dat requires x to be an object of class data.frame but the object you've provided me with is of class(es): ", + stop("vis_dat requires a data.frame but the object I see has class/es: ", paste(class(x), collapse = ", ")) } From 5620c8aa9755000d1fa5587fcb8a8695c043d469 Mon Sep 17 00:00:00 2001 From: Nic Date: Thu, 22 Nov 2018 20:53:11 +0000 Subject: [PATCH 5/5] #101 Add test_if_dataframe to all functions and add associated tests --- DESCRIPTION | 3 ++- R/internals.R | 25 +++++++++++++++++++++++++ R/vis-compare.R | 6 ++++++ R/vis-cor.R | 3 +++ R/vis-dat.R | 5 +---- R/vis-expect.R | 3 +++ R/vis-guess.R | 3 +++ R/vis-miss.R | 3 +++ man/test_if_dataframe.Rd | 26 ++++++++++++++++++++++++++ tests/testthat/test-vis-compare.R | 6 ++++++ tests/testthat/test-vis-cor.R | 4 ++++ tests/testthat/test-vis-dat.R | 2 +- tests/testthat/test-vis-expect.R | 3 +++ tests/testthat/test-vis-guess.R | 4 ++++ tests/testthat/test-vis-miss.R | 4 ++++ 15 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 man/test_if_dataframe.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 131a3f2..f236d67 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -13,7 +13,8 @@ Authors@R: c( comment = "Mara Averick reviewed the package for rOpenSci, see https://github.com/ropensci/onboarding/issues/87"), person("Stuart", "Lee", role = c("ctb")), - person("Earo", "Wang", role = c("ctb")) + person("Earo", "Wang", role = c("ctb")), + person("Nic", "Crane", role = c("ctb")) ) Description: Create preliminary exploratory data visualisations of an entire dataset to identify problems or unexpected features using 'ggplot2'. diff --git a/R/internals.R b/R/internals.R index ca450b4..7a0c61e 100644 --- a/R/internals.R +++ b/R/internals.R @@ -265,3 +265,28 @@ all_numeric <- function(x, ...){ all(as.logical(lapply(x, is.numeric))) } # Can I capture moving from a value to NA, or, from NA to another value? + + +#' Test if input is a data.frame +#' +#' @param x object +#' +#' @return an error if input (x) is not a data.frame +#' +#' @examples +#' \dontrun{ +#' # success +#' test_if_dataframe(airquality) +#' #fail +#' test_if_dataframe(AirPassengers) +#' } +#' +test_if_dataframe <- function(x){ + if (!inherits(x, "data.frame")) { + stop("vis_dat requires a data.frame but the object I see has class/es: ", + paste(class(x), collapse = ", "), call.=FALSE) + } +} + + + diff --git a/R/vis-compare.R b/R/vis-compare.R index 3f1e19e..2a26a58 100644 --- a/R/vis-compare.R +++ b/R/vis-compare.R @@ -30,6 +30,12 @@ vis_compare <- function(df1, # make a TRUE/FALSE matrix of the data. # Tells us whether it is the same (true) as the other dataset, or not (false) + # throw error if df1 not data.frame + test_if_dataframe(df1) + + # throw error if df2 not data.frame + test_if_dataframe(df2) + if (!identical(dim(df1), dim(df2))) { stop("vis_compare requires identical dimensions of df1 and df2") } diff --git a/R/vis-cor.R b/R/vis-cor.R index 00a6ff1..8999677 100644 --- a/R/vis-cor.R +++ b/R/vis-cor.R @@ -28,6 +28,9 @@ vis_cor <- function(data, na_action = "pairwise.complete.obs", ...){ + # throw error if data not data.frame + test_if_dataframe(data) + if (!all_numeric(data)) { stop("data input can only contain numeric values, please subset the data to the numeric values you would like.") } else { diff --git a/R/vis-dat.R b/R/vis-dat.R index 9c7361c..3d38e71 100644 --- a/R/vis-dat.R +++ b/R/vis-dat.R @@ -65,10 +65,7 @@ vis_dat <- function(x, large_data_size = 900000) { # throw error if x not data.frame - if(!(inherits(x, "data.frame"))){ - stop("vis_dat requires a data.frame but the object I see has class/es: ", - paste(class(x), collapse = ", ")) - } + test_if_dataframe(x) # add warning for large data if (ncol(x) * nrow(x) > large_data_size && warn_large_data){ diff --git a/R/vis-expect.R b/R/vis-expect.R index 2ad66d0..916e997 100644 --- a/R/vis-expect.R +++ b/R/vis-expect.R @@ -61,6 +61,9 @@ #' vis_expect <- function(data, expectation, show_perc = TRUE){ + # throw error if data not data.frame + test_if_dataframe(data) + data_expect <- expect_frame(data, expectation) # calculate the overall % expecations to display in legend ------------------- diff --git a/R/vis-guess.R b/R/vis-guess.R index 35d74b8..1a616ec 100644 --- a/R/vis-guess.R +++ b/R/vis-guess.R @@ -45,6 +45,9 @@ #' @export vis_guess <- function(x, palette = "default"){ + # throw error if x not data.frame + test_if_dataframe(x) + # x = messy_df # suppress warnings here as this is just a note about combining classes d <- suppressWarnings(vis_gather_(x)) %>% diff --git a/R/vis-miss.R b/R/vis-miss.R index b1d8406..96fe558 100644 --- a/R/vis-miss.R +++ b/R/vis-miss.R @@ -68,6 +68,9 @@ vis_miss <- function(x, large_data_size = 900000, warn_large_data = TRUE){ + # throw error if x not data.frame + test_if_dataframe(x) + # add warning for large data if (ncol(x) * nrow(x) > large_data_size && warn_large_data) { stop("Data exceeds recommended size for visualisation, please consider diff --git a/man/test_if_dataframe.Rd b/man/test_if_dataframe.Rd new file mode 100644 index 0000000..05b9599 --- /dev/null +++ b/man/test_if_dataframe.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/internals.R +\name{test_if_dataframe} +\alias{test_if_dataframe} +\title{Test if input is a data.frame} +\usage{ +test_if_dataframe(x) +} +\arguments{ +\item{x}{object} +} +\value{ +an error if input (x) is not a data.frame +} +\description{ +Test if input is a data.frame +} +\examples{ +\dontrun{ +# success +test_if_dataframe(airquality) +#fail +test_if_dataframe(AirPassengers) +} + +} diff --git a/tests/testthat/test-vis-compare.R b/tests/testthat/test-vis-compare.R index 618f91f..b34f2f4 100644 --- a/tests/testthat/test-vis-compare.R +++ b/tests/testthat/test-vis-compare.R @@ -19,3 +19,9 @@ test_that("vis_compare will not accept two dataframes of differing dims",{ expect_error( vis_compare(iris, iris_add)) }) + +test_that("vis_compare fails when an object of the wrong class is provided", { + testthat::expect_error(vis_compare(iris, AirPassengers)) + testthat::expect_error(vis_compare(AirPassengers, iris)) + testthat::expect_error(vis_compare(AirPassengers, AirPassengers)) +}) diff --git a/tests/testthat/test-vis-cor.R b/tests/testthat/test-vis-cor.R index 7bb4c69..197b3d6 100644 --- a/tests/testthat/test-vis-cor.R +++ b/tests/testthat/test-vis-cor.R @@ -13,3 +13,7 @@ test_that("vis_cor creates the right plot",{ test_that("vis_cor sends an error when used with the wrong data",{ testthat::expect_error(vis_cor(iris)) }) + +test_that("vis_cor fails when an object of the wrong class is provided", { + testthat::expect_error(vis_cor(AirPassengers)) +}) diff --git a/tests/testthat/test-vis-dat.R b/tests/testthat/test-vis-dat.R index 048619c..6653d1a 100644 --- a/tests/testthat/test-vis-dat.R +++ b/tests/testthat/test-vis-dat.R @@ -33,5 +33,5 @@ test_that("vis_dat fails when the wrong palette is provided",{ }) test_that("vis_dat fails when an object of the wrong class is provided", { - expect_error(vis_dat(AirPassengers)) + testthat::expect_error(vis_dat(AirPassengers)) }) diff --git a/tests/testthat/test-vis-expect.R b/tests/testthat/test-vis-expect.R index 317d8f5..eacfb00 100644 --- a/tests/testthat/test-vis-expect.R +++ b/tests/testthat/test-vis-expect.R @@ -25,3 +25,6 @@ test_that("vis_expect creates the right plot",{ vis_expect_plot_show_perc_true) }) +test_that("vis_expect fails when an object of the wrong class is provided", { + testthat::expect_error(vis_expect(AirPassengers, ~.x < 20)) +}) diff --git a/tests/testthat/test-vis-guess.R b/tests/testthat/test-vis-guess.R index 3e2b152..340ab2e 100644 --- a/tests/testthat/test-vis-guess.R +++ b/tests/testthat/test-vis-guess.R @@ -16,3 +16,7 @@ test_that("vis_guess creates the right plot",{ test_that("vis_guess fails when the wrong palette is provided",{ testthat::expect_error(vis_guess(typical_data, palette = "wat")) }) + +test_that("vis_guess fails when an object of the wrong class is provided", { + testthat::expect_error(vis_guess(AirPassengers)) +}) diff --git a/tests/testthat/test-vis-miss.R b/tests/testthat/test-vis-miss.R index da15b16..b53c477 100644 --- a/tests/testthat/test-vis-miss.R +++ b/tests/testthat/test-vis-miss.R @@ -19,3 +19,7 @@ test_that("vis_miss creates the right plot",{ vdiffr::expect_doppelganger("vis_miss show percent in columns", vis_miss_plot_show_perc_col) vdiffr::expect_doppelganger("vis_miss no show percent in columns", vis_miss_plot_show_perc_col_t) }) + +test_that("vis_miss fails when an object of the wrong class is provided", { + testthat::expect_error(vis_miss(AirPassengers)) +})