From aa7a73342e805eba30cb01792707bf687617193a Mon Sep 17 00:00:00 2001 From: GidonFrischkorn Date: Thu, 8 Feb 2024 13:41:06 +0100 Subject: [PATCH 1/3] Update data check and add deg2rad & rad2deg --- NAMESPACE | 2 ++ R/helpers-data.R | 43 +++++++++++++++++++++--------- man/circle_transform.Rd | 30 +++++++++++++++++++++ tests/testthat/test-helpers-data.R | 14 +++++++++- 4 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 man/circle_transform.Rd diff --git a/NAMESPACE b/NAMESPACE index 35d53339..ebc3ec4f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -25,6 +25,7 @@ export(calc_error_relative_to_nontargets) export(check_data) export(configure_model) export(dIMM) +export(deg2rad) export(dmixture2p) export(dmixture3p) export(dsdm) @@ -46,6 +47,7 @@ export(qmixture2p) export(qmixture3p) export(qsdm) export(rIMM) +export(rad2deg) export(rmixture2p) export(rmixture3p) export(rsdm) diff --git a/R/helpers-data.R b/R/helpers-data.R index 1b733b03..deff103a 100644 --- a/R/helpers-data.R +++ b/R/helpers-data.R @@ -55,14 +55,11 @@ check_data.default <- function(model, data, formula) { #' @export check_data.vwm <- function(model, data, formula) { resp_name <- get_response(formula$formula) - if (max(abs(data[[resp_name]]), na.rm=T) > 10) { - data[[resp_name]] <- data[[resp_name]]*pi/180 - warning('It appears your response variable is in degrees. We will transform it to radians.') + if (max(abs(data[[resp_name]]), na.rm = T) > 2*pi) { + warning('It appears your response variable is in degrees.\n + The model will continue to run, but the results may be compromised.') } - # wrap recoded responses around the circle (range = -pi to pi) - data[[resp_name]] <- wrap(data[[resp_name]]) - data = NextMethod("check_data") return(data) @@ -72,9 +69,9 @@ check_data.vwm <- function(model, data, formula) { #' @export check_data.nontargets <- function(model, data, formula) { non_targets <- model$vars$non_targets - if (max(abs(data[,non_targets]), na.rm=T) > 10) { - data[,non_targets] <- data[,non_targets]*pi/180 - warning('It appears your non_target variables are in degrees. We will transform it to radians.') + if (max(abs(data[,non_targets]), na.rm = T) > 2*pi) { + warning('It appears at least one of your non_target variables are in degrees.\n + The model will continue to run, but the results may be compromised.') } setsize <- model$vars$setsize @@ -98,9 +95,6 @@ check_data.nontargets <- function(model, data, formula) { '`non_targets` is more than max(setsize)-1') } - # wrap non_target variables around the circle (range = -pi to pi) - data[,non_targets] <- wrap(data[,non_targets]) - # create index variables for non_targets and correction variable for theta due to setsize lure_idx_vars <- paste0('LureIdx',1:(max_setsize - 1)) for (i in 1:(max_setsize - 1)) { @@ -180,3 +174,28 @@ wrap <- function(x, radians=TRUE) { return(((x+180) %% (2*180)) - 180) } } + +#' @title Convert degrees to radians or radians to degrees. +#' @description +#' The helper functions `deg2rad` and `rad2deg` should add convenience in transforming +#' data from degrees to radians and from radians to degrees. +#' +#' @name circle_transform +#' @param deg A numeric vector of values in degrees. +#' @param rad A numeric vector of values in radians. +#' @return A numeric vector of the same length as `deg` or `rad`. +#' @keywords transform +#' @export +#' @examples +#' degrees <- runif(100, min = 0, max = 360) +#' radians <- deg2rad(degrees) +#' degrees_again <- rad2deg(radians) +deg2rad <- function(deg){ + deg * pi / 180 +} + +#' @rdname circle_transform +#' @export +rad2deg <- function(rad){ + rad * 180 / pi +} diff --git a/man/circle_transform.Rd b/man/circle_transform.Rd new file mode 100644 index 00000000..fa9c9e52 --- /dev/null +++ b/man/circle_transform.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/helpers-data.R +\name{circle_transform} +\alias{circle_transform} +\alias{deg2rad} +\alias{rad2deg} +\title{Convert degrees to radians or radians to degrees.} +\usage{ +deg2rad(deg) + +rad2deg(rad) +} +\arguments{ +\item{deg}{A numeric vector of values in degrees.} + +\item{rad}{A numeric vector of values in radians.} +} +\value{ +A numeric vector of the same length as \code{deg} or \code{rad}. +} +\description{ +The helper functions \code{deg2rad} and \code{rad2deg} should add convenience in transforming +data from degrees to radians and from radians to degrees. +} +\examples{ + degrees <- runif(100, min = 0, max = 360) + radians <- deg2rad(degrees) + degrees_again <- rad2deg(radians) +} +\keyword{transform} diff --git a/tests/testthat/test-helpers-data.R b/tests/testthat/test-helpers-data.R index 42b879ea..3447f80e 100644 --- a/tests/testthat/test-helpers-data.R +++ b/tests/testthat/test-helpers-data.R @@ -11,7 +11,8 @@ test_that("check_data() produces expected errors and warnings", { expect_warning(check_data(ml(non_targets = 'x', setsize=2, spaPos = 'z'), data.frame(y = 12, x = 1, z = 2), brms::bf(y ~ 1)), - "It appears your response variable is in degrees. We will transform it to radians.") + "It appears your response variable is in degrees.\n + The model will continue to run, but the results may be compromised.") expect_silent(check_data(ml(non_targets = 'x', setsize=2, spaPos = 'z'), data.frame(y = 1, x = 1, z = 2), brms::bf(y ~ 1))) } @@ -71,3 +72,14 @@ test_that("wrap(x) returns the correct value for values between (3*pi,4*pi)", { x <- 3*pi+1 expect_equal(wrap(x), -(pi-1)) }) + + +test_that("deg2rad returns the correct values for 0, 180, 360", { + x <- c(0,90,180) + expect_equal(round(deg2rad(x),2),c(0.00,1.57,3.14)) +}) + +test_that("rad2deg returns the correct values for 0, pi/2, 2*pi", { + x <- c(0, pi/2, 2*pi) + expect_equal(round(rad2deg(x),2),c(0,90,360)) +}) From 73bd27eb0cce839a50796e98f7e98b65fc5264b5 Mon Sep 17 00:00:00 2001 From: Ven Popov Date: Thu, 8 Feb 2024 15:00:08 +0100 Subject: [PATCH 2/3] Update helpers-data.R Add " The model requires the response variable to be in radians.\n" to the warning so that users don't wonder what is the problem --- R/helpers-data.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/R/helpers-data.R b/R/helpers-data.R index deff103a..47b83272 100644 --- a/R/helpers-data.R +++ b/R/helpers-data.R @@ -57,7 +57,8 @@ check_data.vwm <- function(model, data, formula) { resp_name <- get_response(formula$formula) if (max(abs(data[[resp_name]]), na.rm = T) > 2*pi) { warning('It appears your response variable is in degrees.\n - The model will continue to run, but the results may be compromised.') + The model requires the response variable to be in radians.\n + The model will continue to run, but the results may be compromised.') } data = NextMethod("check_data") @@ -71,6 +72,7 @@ check_data.nontargets <- function(model, data, formula) { non_targets <- model$vars$non_targets if (max(abs(data[,non_targets]), na.rm = T) > 2*pi) { warning('It appears at least one of your non_target variables are in degrees.\n + The model requires these variable to be in radians.\n The model will continue to run, but the results may be compromised.') } From 37cc6c057077e5d7118bbe2d9f21856591c70c81 Mon Sep 17 00:00:00 2001 From: Ven Popov Date: Thu, 8 Feb 2024 15:01:41 +0100 Subject: [PATCH 3/3] Update test-helpers-data.R update test based on my addition to the warning --- tests/testthat/test-helpers-data.R | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/testthat/test-helpers-data.R b/tests/testthat/test-helpers-data.R index 3447f80e..b60f8c45 100644 --- a/tests/testthat/test-helpers-data.R +++ b/tests/testthat/test-helpers-data.R @@ -11,8 +11,7 @@ test_that("check_data() produces expected errors and warnings", { expect_warning(check_data(ml(non_targets = 'x', setsize=2, spaPos = 'z'), data.frame(y = 12, x = 1, z = 2), brms::bf(y ~ 1)), - "It appears your response variable is in degrees.\n - The model will continue to run, but the results may be compromised.") + "It appears your response variable is in degrees.\n") expect_silent(check_data(ml(non_targets = 'x', setsize=2, spaPos = 'z'), data.frame(y = 1, x = 1, z = 2), brms::bf(y ~ 1))) }