From 0c87305d0edca3baf9ef0954354c8024e9169383 Mon Sep 17 00:00:00 2001 From: LukasTang Date: Sun, 15 Sep 2024 22:29:14 +0200 Subject: [PATCH] Concluded development work, added some unit tests and improved documentation and namespace management. --- DESCRIPTION | 2 +- NAMESPACE | 3 ++ R/standard_summary.R | 22 +++++------ man/standard_summary.Rd | 41 +++++++++++++++++++++ tests/testthat/test-standard-summary.R | 35 ++++++++++-------- tests/testthat/test_test-standard-summary.R | 0 6 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 man/standard_summary.Rd create mode 100644 tests/testthat/test_test-standard-summary.R diff --git a/DESCRIPTION b/DESCRIPTION index 49f92c88cc..04d3506c2c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: dplyr Title: A Grammar of Data Manipulation -Version: 1.1.4.9000 +Version: 1.1.4.9001 Authors@R: c( person("Hadley", "Wickham", , "hadley@posit.co", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-4757-117X")), diff --git a/NAMESPACE b/NAMESPACE index 5689062356..0513fd6402 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -431,6 +431,7 @@ export(src_mysql) export(src_postgres) export(src_sqlite) export(src_tbls) +export(standard_summary) export(starts_with) export(summarise) export(summarise_) @@ -492,6 +493,8 @@ importFrom(methods,setOldClass) importFrom(pillar,glimpse) importFrom(pillar,tbl_sum) importFrom(pillar,type_sum) +importFrom(stats,quantile) +importFrom(stats,sd) importFrom(stats,setNames) importFrom(stats,update) importFrom(tibble,add_row) diff --git a/R/standard_summary.R b/R/standard_summary.R index a1833aa668..681ebe1862 100644 --- a/R/standard_summary.R +++ b/R/standard_summary.R @@ -3,14 +3,14 @@ #' This function calculates standard summary statistics for specified variables in a data frame. #' #' @param df A data frame. -#' @param vars A character vector specifying the variables for which summary statistics should be calculated. +#' @param vars A character vector specifying the numeric variables for which summary statistics should be calculated. #' @param functions A list of functions to be applied to each variable. The default functions include mean, standard deviation, minimum, 10th percentile, 25th percentile, median, 75th percentile, 90th percentile, maximum, count, and count of missing values. #' #' @return A data frame containing the calculated summary statistics. #' #' @examples #' df <- data.frame( -#' groups = c("a","a","a","b","c") +#' groups = c("a","a","a","b","c"), #' var1 = c(1, 2, 3, 4, 5), #' var2 = c(6, 7, NA, 9, 10) #' ) @@ -19,11 +19,7 @@ #' summary <- df %>% group_by(groups) %>% standard_summary(c("var1", "var2")) #' print(summary) #' -#' @import dplyr -#' @import tidyr -#' @import stringr -#' @importFrom stats mean sd min quantile max -#' @importFrom base length which is.na +#' @importFrom stats sd quantile #' #' @export standard_summary <- function(df, vars, functions = list( @@ -41,10 +37,14 @@ standard_summary <- function(df, vars, functions = list( ) { gg <- as.character(groups(df)) summary_res <- df %>% - select(!!vars) %>% + select(all_of(vars)) %>% summarise(across(.cols = c(!!vars), .fns = functions, .names = "{.col}xx_xx{.fn}")) %>% ungroup() %>% - pivot_longer(cols = contains("xx")) %>% + pivot_longer(cols = contains("xx_xx")) %>% + mutate(value = as.numeric(value)) %>% separate(name, into = c("VARIABLE", "STAT"), sep = "xx_xx") %>% - pivot_wider(id_cols = c(gg, "VARIABLE"), values_from = value, names_from = STAT) -} \ No newline at end of file + pivot_wider(id_cols = c(gg, "VARIABLE"), values_from = value, names_from = STAT) %>% + as.data.frame() + return(summary_res) + +} diff --git a/man/standard_summary.Rd b/man/standard_summary.Rd new file mode 100644 index 0000000000..5c586a7b74 --- /dev/null +++ b/man/standard_summary.Rd @@ -0,0 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/standard_summary.R +\name{standard_summary} +\alias{standard_summary} +\title{Standard Summary} +\usage{ +standard_summary( + df, + vars, + functions = list(mean = ~mean(.x, na.rm = TRUE), sd = ~sd(.x, na.rm = TRUE), min = + ~min(.x, na.rm = TRUE), q10 = ~quantile(.x, 0.1, na.rm = TRUE), q25 = ~quantile(.x, + 0.25, na.rm = TRUE), med = ~quantile(.x, 0.5, na.rm = TRUE), q75 = ~quantile(.x, + 0.75, na.rm = TRUE), q90 = ~quantile(.x, 0.9, na.rm = TRUE), max = ~max(.x, na.rm = + TRUE), n = ~n(), nmiss = ~length(which(is.na(.x)))) +) +} +\arguments{ +\item{df}{A data frame.} + +\item{vars}{A character vector specifying the variables for which summary statistics should be calculated.} + +\item{functions}{A list of functions to be applied to each variable. The default functions include mean, standard deviation, minimum, 10th percentile, 25th percentile, median, 75th percentile, 90th percentile, maximum, count, and count of missing values.} +} +\value{ +A data frame containing the calculated summary statistics. +} +\description{ +This function calculates standard summary statistics for specified variables in a data frame. +} +\examples{ +df <- data.frame( + groups = c("a","a","a","b","c"), + var1 = c(1, 2, 3, 4, 5), + var2 = c(6, 7, NA, 9, 10) +) + +# Calculate standard summary statistics for var1 and var2 +summary <- df \%>\% group_by(groups) \%>\% standard_summary(c("var1", "var2")) +print(summary) + +} diff --git a/tests/testthat/test-standard-summary.R b/tests/testthat/test-standard-summary.R index 1125639199..320ab8c3d0 100644 --- a/tests/testthat/test-standard-summary.R +++ b/tests/testthat/test-standard-summary.R @@ -1,21 +1,26 @@ test_that("standard summary returns correct results", { # Create a test data frame df <- data.frame( - x = c(1, 2, 3, 4, 5), - y = c(6, 7, 8, 9, 10) + groups = c("a","a","a","b","c"), + var1 = c(1, 2, 3, 4, 5), + var2 = c(6, 7, NA, 9, 10) ) - - # Call the standard summary function - result <- standard_summary(df) - + + # Calculate standard summary statistics for var1 and var2 + result <- starwars %>% + filter(!is.na(sex)) %>% + group_by(sex) %>% + standard_summary(vars=c("height", "mass","birth_year")) + # Check if the result is a data frame - expect_is(result, "data.frame") - - # Check if the result has the correct number of rows and columns - expect_equal(nrow(result), 2) - expect_equal(ncol(result), 2) - + expect_true(is.data.frame(result)) + +# Check if the result has the correct number of rows and columns + expect_equal(nrow(result), 12) + expect_equal(df_n_col(result), 13) + # Check if the result contains the correct summary statistics - expect_equal(result[1, "x"], 3) - expect_equal(result[2, "y"], 8) -}) \ No newline at end of file + expect_equal(result[1,"min"], 150) + expect_equal(result[2, "med"] , 55) + expect_equal(result[7,"nmiss"],3) +}) diff --git a/tests/testthat/test_test-standard-summary.R b/tests/testthat/test_test-standard-summary.R new file mode 100644 index 0000000000..e69de29bb2