Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions R/acro_tables.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,42 @@ acro_crosstab <- function(index, columns, values = NULL, rownames = NULL, colnam
stop("ACRO has not been initialised. Please first call acro_init()")
}

py_table <- acroEnv$ac$crosstab(index, columns, values = values, rownames = rownames, colnames = colnames, aggfunc = aggfunc, margins = margins, margins_name = margins_name, dropna = dropna, normalize = normalize, show_suppressed = show_suppressed)
# Convert the values into a NumPy array so that the Python ACRO crosstab function accepts them
np <- reticulate::import("numpy", convert = TRUE)
py_values <- if (!is.null(values)) np$array(values) else NULL

py_table <- tryCatch(
{
acroEnv$ac$crosstab(index, columns, values = py_values, rownames = rownames, colnames = colnames, aggfunc = aggfunc, margins = margins, margins_name = margins_name, dropna = dropna, normalize = normalize, show_suppressed = show_suppressed)
},
error = function(e) {
# Check if Python threw the ValueError about an unsupported aggfunc
if (grepl("ValueError: aggfunc", e$message)) {
stop(
sprintf("Unsupported aggregation function provided: '%s'. Allowed functions are: mean, median, sum, std, count, mode.", aggfunc),
call. = FALSE
)
}
# 2. Check if Python threw the missing values column error
else if (grepl("If you pass an aggregation function to crosstab", e$message)) {
stop(
"If you pass an aggregation function to crosstab, you must also specify a single values column to aggregate over.",
call. = FALSE
)
}
# any other unexpected errors
else {
stop(e) # nocov
}
}
)

table <- reticulate::py_to_r(py_table)

return(table)
}


#' Compute a simple cross tabulation of two (or more) factors.
#'
#' @param index Values to group by in the rows.
Expand Down Expand Up @@ -152,7 +182,23 @@ acro_pivot_table <- function(data, values = NULL, index = NULL, columns = NULL,
if (is.null(acroEnv$ac)) {
stop("ACRO has not been initialised. Please first call acro_init()")
}
py_table <- acroEnv$ac$pivot_table(data, values = values, index = index, columns = columns, aggfunc = aggfunc)

py_table <- tryCatch(
{
acroEnv$ac$pivot_table(data, values = values, index = index, columns = columns, aggfunc = aggfunc)
},
error = function(e) {
if (grepl("aggfunc", e$message, ignore.case = TRUE)) {
stop(
sprintf("Unsupported aggregation function provided: '%s'. Allowed functions are: mean, median, sum, std, count, mode.", aggfunc),
call. = FALSE
)
} else {
stop(e) # nocov
}
}
)

table <- reticulate::py_to_r(py_table)
return(table)
}
Expand Down
41 changes: 41 additions & 0 deletions tests/testthat/test-acro_crosstab.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,44 @@ test_that("acro_crosstab works with margins", {

expect_equal(unname(as.matrix(r_table)), unname(as.matrix(p_table)))
})

test_that("acro_crosstab works with aggregation function", {
# Creating the data frame with the specified values and row names
testthat::skip_on_cran()
expected_table <- data.frame(
convenient = c(3.25, 3.23, 3.25),
inconv = c(3.26, 3.26, 3.24)
)

# Assigning row names to the data frame
row.names(expected_table) <- c("not_recom", "priority", "recommended")

acro_init()
table <- acro_crosstab(index = nursery_data[, c("health")], columns = nursery_data[, c("finance")], values = nursery_data[, c("children")], aggfunc = "mean")
expect_equal(table[, -1, drop = FALSE], expected_table[, -1, drop = FALSE], tolerance = 0.01)
})

test_that("acro_crosstab throws an error for unsupported aggregation functions", {
acro_init()
expect_error(
acro_crosstab(
index = nursery_data$health,
columns = nursery_data$finance,
values = nursery_data$children,
aggfunc = "max"
),
"Unsupported aggregation function provided"
)
})

test_that("acro_crosstab throws an error for missing values", {
acro_init()
expect_error(
acro_crosstab(
index = nursery_data$health,
columns = nursery_data$finance,
aggfunc = "mean"
),
"If you pass an aggregation function to crosstab"
)
})
13 changes: 13 additions & 0 deletions tests/testthat/test-acro_pivot_table.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,16 @@ test_that("acro_pivot_table works", {
table <- acro_pivot_table(data = nursery_data, index = "parents", values = "children", aggfunc = list("mean", "std"))
expect_equal(table[, -1, drop = FALSE], expected_table[, -1, drop = FALSE])
})

test_that("acro_pivot_table throws an error for unsupported aggregation functions", {
acro_init()
expect_error(
acro_pivot_table(
data = nursery_data,
index = nursery_data$parents,
values = nursery_data$children,
aggfunc = "max"
),
"Unsupported aggregation function provided"
)
})
Loading