Repository: beckerbenj/eatGADS
Pull request #128: check4Stata: Add first helper functions
Author: login: weigtnik
Labels: name: enhancement
description: New feature or request
Created: 2025-05-14T17:22:10Z | Merged: 2025-05-26T15:57:15Z

This PR addresses #110, adding two helper functions that the main/wrapper function will use.
- `checkIntOverflow` is used to detect labeled (whole number/integer) values that exceed the highest integer R can work with, which would cause problems when exporting to `.dta` because Stata only allows for labeled *integers*.
- `checkLabeledFractionals` addresses said restriction of Stata by looking for labeled fractional values (or fractional values tagged as missing).

This is not urgent, and I will be happy about all the feedback you can provide!


Diff:
diff --git a/DESCRIPTION b/DESCRIPTION
index 9159629a..41d1f50e 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -19,5 +19,5 @@ Suggests:
     rmarkdown,
     covr,
     tidyr (>= 1.1.0)
-RoxygenNote: 7.2.3
+RoxygenNote: 7.3.2
 VignetteBuilder: knitr
diff --git a/NAMESPACE b/NAMESPACE
index 2a23777b..eff2ce52 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -123,6 +123,8 @@ export(changeVarNames)
 export(check4SPSS)
 export(checkEmptyValLabels)
 export(checkFormat)
+export(checkIntOverflow)
+export(checkLabeledFractionals)
 export(checkMissingValLabels)
 export(checkMissings)
 export(checkMissingsByValues)
diff --git a/R/checkIntOverflow.R b/R/checkIntOverflow.R
new file mode 100644
index 00000000..f0adc7df
--- /dev/null
+++ b/R/checkIntOverflow.R
@@ -0,0 +1,69 @@
+#' Check a \code{GADSdat} for large labeled whole-number values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of labeled whole-number values
+#'  that would be too large for R to handle if they were coerced \code{as.integer()}.
+#'
+#' According to its documentation, R can only handle \code{\link[base:integer]{integer}}
+#' values of up to (roughly) \eqn{\pm 2 \times 10^9} (2,147,483,647 to be exact;
+#' c.f. \code{\link[base:.Machine]{.Machine}$integer.max}).
+#' This restriction is relevant when exporting a \code{GADSdat} to \code{.dta}
+#' and only when any value exceeding the limit is also labeled (or tagged as missing).
+#' This is because Stata only accepts labeled \emph{integer} (not labeled \emph{floating-point};
+#' c.f. \code{\link[checkLabeledFractionals()]{checkLabeledFractionals}} in this package)
+#' values. \code{haven}'s \code{\link[haven:write_dta]{write_dta}} function will therefore
+#' try to coerce any labeled values \code{as.integer()}. Unlabeled values, however, will
+#' stay generic \code{numeric} values that have a higher limit.
+#'
+#'@param GADSdat A \code{GADSdat} object.
+#'
+#'@return Returns a \code{data.frame}, listing the affected \code{varName}s,
+#' the large whole-number \code{value}s, their respective \code{missings} tags,
+#' and whether they actually occur in the data (\code{empty}).
+#' The \code{rownum}s of the affected rows in \code{GADSdat$labels} are also
+#' provided in a separate column as a fail safe.
+#'
+#'@examples
+#' # Introduce a fractional value into meta data
+#' pisa2 <- changeMissings(GADSdat = pisa,
+#'                         varName = "schtype",
+#'                         value = 9999999999,
+#'                         missings = "miss")
+#' checkIntOverflow(pisa2)
+#'
+#'@export
+checkIntOverflow <- function(GADSdat) {
+  check_GADSdat(GADSdat)
+  labels <- GADSdat$labels
+
+  out <- data.frame(varName = character(),
+                    value = numeric(),
+                    missings = character(),
+                    empty = logical(),
+                    rownum = integer())
+
+  huge_labeled_number_rows <- which(abs(labels$value) > .Machine$integer.max &
+                                      labels$value %% 1 == 0)
+
+  if (length(huge_labeled_number_rows) == 0) {
+    return(out)
+  }
+
+  out[1:length(huge_labeled_number_rows), c("varName",
+                                            "value",
+                                            "missings")] <-
+    labels[huge_labeled_number_rows, c("varName",
+                                       "value",
+                                       "missings")]
+  out$rownum <- huge_labeled_number_rows
+
+  varlist <- unique(out$varName)
+  empty_values <- checkEmptyValLabels(GADSdat = GADSdat,
+                                      vars = varlist)
+  for(varname in varlist) {
+    vallist <- out[out$varName == varname, "value"]
+    out[out$varName == varname, "empty"] <- vallist %in% empty_values[[varname]]$value
+  }
+
+  rownames(out) <- NULL
+  return(out)
+}
diff --git a/R/checkLabeledFractionals.R b/R/checkLabeledFractionals.R
new file mode 100644
index 00000000..7c0fbf6c
--- /dev/null
+++ b/R/checkLabeledFractionals.R
@@ -0,0 +1,60 @@
+#' Check a \code{GADSdat} for labeled fractional values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of fractional values in its metadata,
+#' including both "truly" labeled values and values tagged as \code{missings}.
+#'
+#' This function is mainly useful to ensure a data set can be saved as a \code{.dta} file.
+#' Unlike, for example, SPSS, Stata only allows for integer values
+#' (and so-called extended missing values) to be labeled
+#' (\href{https://www.stata.com/manuals/u12.pdf#u12.6.3Valuelabels}{Stata manual: 12.6.3}).
+#' Trying to export (meta) data with labeled fractional values would therefore cause problems
+#' and run into an error from \code{haven}'s \code{\link[haven:write_dta]{write_dta}} function.
+#'
+#'@param GADSdat A \code{GADSdat} object.
+#'
+#'@return Returns a \code{data.frame}, listing the affected \code{varName}s,
+#' the labeled fractional \code{value}s, their respective \code{missings} tags,
+#' and whether they actually occur in the data (\code{empty}).
+#'
+#'@examples
+#' # Introduce a fractional value into meta data
+#' pisa2 <- recodeGADS(GADSdat = pisa,
+#'                     varName = "schtype",
+#'                     oldValues = 2,
+#'                     newValues = .5)
+#' checkLabeledFractionals(pisa2)
+#'
+#'@export
+checkLabeledFractionals <- function(GADSdat) {
+  check_GADSdat(GADSdat)
+  labels <- GADSdat$labels
+
+  out <- data.frame(varName = character(),
+                    value = numeric(),
+                    missings = character(),
+                    empty = logical())
+
+  labeled_fractional_rows <- which(labels$value %% 1 != 0)
+
+  if (length(labeled_fractional_rows) == 0) {
+    return(out)
+  }
+
+  out[1:length(labeled_fractional_rows), c("varName",
+                                           "value",
+                                           "missings")] <-
+    labels[labeled_fractional_rows, c("varName",
+                                      "value",
+                                      "missings")]
+
+  varlist <- unique(out$varName)
+  empty_values <- checkEmptyValLabels(GADSdat = GADSdat,
+                                      vars = varlist)
+  for(varname in varlist) {
+    vallist <- out[out$varName == varname, "value"]
+    out[out$varName == varname, "empty"] <- vallist %in% empty_values[[varname]]$value
+  }
+
+  rownames(out) <- NULL
+  return(out)
+}
diff --git a/man/checkIntOverflow.Rd b/man/checkIntOverflow.Rd
new file mode 100644
index 00000000..2bfbc596
--- /dev/null
+++ b/man/checkIntOverflow.Rd
@@ -0,0 +1,43 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkIntOverflow.R
+\name{checkIntOverflow}
+\alias{checkIntOverflow}
+\title{Check a \code{GADSdat} for large labeled whole-number values.}
+\usage{
+checkIntOverflow(GADSdat)
+}
+\arguments{
+\item{GADSdat}{A \code{GADSdat} object.}
+}
+\value{
+Returns a \code{data.frame}, listing the affected \code{varName}s,
+the large whole-number \code{value}s, their respective \code{missings} tags,
+and whether they actually occur in the data (\code{empty}).
+The \code{rownum}s of the affected rows in \code{GADSdat$labels} are also
+provided in a separate column as a fail safe.
+}
+\description{
+Check a \code{GADSdat} object for any occurrences of labeled whole-number values
+ that would be too large for R to handle if they were coerced \code{as.integer()}.
+}
+\details{
+According to its documentation, R can only handle \code{\link[base:integer]{integer}}
+values of up to (roughly) \eqn{\pm 2 \times 10^9} (2,147,483,647 to be exact;
+c.f. \code{\link[base:.Machine]{.Machine}$integer.max}).
+This restriction is only relevant when exporting a \code{GADSdat} to \code{.dta}
+and only when any value exceeding the limit is also labeled (or tagged as missing).
+This is because Stata only accepts labeled \emph{integer} (not labeled \emph{floating-point};
+c.f. \code{\link[checkLabeledFractionals()]{checkLabeledFractionals}} in this package)
+values. \code{haven}'s \code{\link[haven:write_dta]{write_dta}} function will therefore
+try to coerce any labeled values \code{as.integer()}. Unlabeled values, however, will
+stay generic \code{numeric} values that have a higher limit.
+}
+\examples{
+# Introduce a fractional value into meta data
+pisa2 <- changeMissings(GADSdat = pisa,
+                        varName = "schtype",
+                        value = 9999999999,
+                        missings = "miss")
+checkIntOverflow(pisa2)
+
+}
diff --git a/man/checkLabeledFractionals.Rd b/man/checkLabeledFractionals.Rd
new file mode 100644
index 00000000..6dc0f584
--- /dev/null
+++ b/man/checkLabeledFractionals.Rd
@@ -0,0 +1,37 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkLabeledFractionals.R
+\name{checkLabeledFractionals}
+\alias{checkLabeledFractionals}
+\title{Check a \code{GADSdat} for labeled fractional values.}
+\usage{
+checkLabeledFractionals(GADSdat)
+}
+\arguments{
+\item{GADSdat}{A \code{GADSdat} object.}
+}
+\value{
+Returns a \code{data.frame}, listing the affected \code{varName}s,
+the labeled fractional \code{value}s, their respective \code{missings} tags,
+and whether they actually occur in the data (\code{empty}).
+}
+\description{
+Check a \code{GADSdat} object for any occurrences of fractional values in its metadata,
+including both "truly" labeled values and values tagged as \code{missings}.
+}
+\details{
+This function is mainly useful to ensure a data set can be saved as a \code{.dta} file.
+Unlike, for example, SPSS, Stata only allows for integer values
+(and so-called extended missing values) to be labeled
+(\href{https://www.stata.com/manuals/u12.pdf#u12.6.3Valuelabels}{Stata manual: 12.6.3}).
+Trying to export (meta) data with labeled fractional values would therefore cause problems
+and run into an error from \code{haven}'s \code{\link[haven:write_dta]{write_dta}} function.
+}
+\examples{
+# Introduce a fractional value into meta data
+pisa2 <- recodeGADS(GADSdat = pisa,
+                    varName = "schtype",
+                    oldValues = 2,
+                    newValues = .5)
+checkLabeledFractionals(pisa2)
+
+}
diff --git a/man/recodeGADS.Rd b/man/recodeGADS.Rd
index 4d91e11a..838a20fd 100644
--- a/man/recodeGADS.Rd
+++ b/man/recodeGADS.Rd
@@ -15,7 +15,7 @@ recodeGADS(
 \arguments{
 \item{GADSdat}{\code{GADSdat} object imported via \code{eatGADS}.}
 
-\item{varName}{Name of the variable to be recoded.}
+\item{varName}{Character vector containing variable names.}
 
 \item{oldValues}{Vector containing the old values.}
 
diff --git a/man/removeValLabels.Rd b/man/removeValLabels.Rd
index 6229ca8d..56d49d32 100644
--- a/man/removeValLabels.Rd
+++ b/man/removeValLabels.Rd
@@ -23,7 +23,7 @@ Remove meta data for specific values (\code{value}) of a single variable (\code{
 This includes value labels and missings tags.
 }
 \details{
-If the argument \code{valLabel} is provided the function checks for \code{value} and \code{valLabel} pairs in the
+If the argument \code{valLabel} is provided, the function checks for \code{value} and \code{valLabel} pairs in the
 meta data that match both arguments.
 }
 \examples{
diff --git a/tests/testthat/test_checkIntOverflow.R b/tests/testthat/test_checkIntOverflow.R
new file mode 100644
index 00000000..2436e6a3
--- /dev/null
+++ b/tests/testthat/test_checkIntOverflow.R
@@ -0,0 +1,73 @@
+# load + generally prepare data
+dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
+df1 <- changeValLabels(GADSdat = dfSAV,
+                       varName = "VAR1",
+                       value = 2,
+                       valLabel = "Apple")
+
+# general output structure to be changed for each test
+outlist <- data.frame(varName = character(),
+                      value = numeric(),
+                      missings = character(),
+                      empty = logical(),
+                      rownum = integer())
+
+test_that("Correctly identify metadata without very large labeled values", {
+  check_result <- checkIntOverflow(GADSdat = df1)
+  expect_equal(check_result, outlist)
+})
+
+test_that("One very large value without any empty labels in the data set", {
+  df2 <- suppressMessages(removeVars(GADSdat = df1,
+                                     vars = c("VAR2", "VAR3")))
+  df2 <- recodeGADS(GADSdat = df2,
+                    varName = "VAR1",
+                    oldValues = 1,
+                    newValues = (2*10^15))
+  check_result <- checkIntOverflow(GADSdat = df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", (2*10^15), "valid", FALSE, 4)
+  expect_equal(check_result, outlist2)
+})
+
+test_that("Two existing labeled value exactly 1 above/below the limit in one variable", {
+  df2 <- recodeGADS(GADSdat = df1,
+                    varName = "VAR1",
+                    oldValues = c(1,-99),
+                    newValues = c(2147483648, -2147483648),
+                    existingMeta = "ignore")
+  check_result <- checkIntOverflow(GADSdat = df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", -2147483648, "miss", FALSE, 1)
+  outlist2[2,] <- list("VAR1", 2147483648, "valid", FALSE, 4)
+  expect_equal(check_result, outlist2)
+})
+
+test_that("Only empty very large labeled values", {
+  df2 <- changeValLabels(GADSdat = df1,
+                         varName = "VAR1",
+                         value = c(-9999999999, 9999999999),
+                         valLabel = c("mbddd", "other"))
+  df2 <- changeMissings(GADSdat = df2,
+                        varName = "VAR1",
+                        value = c(-9999999999, 9999999999),
+                        missings = c("miss", "valid"))
+  check_result <- checkIntOverflow(GADSdat = df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", -9999999999, "miss", TRUE, 1)
+  outlist2[2,] <- list("VAR1", 9999999999, "valid", TRUE, 6)
+  expect_equal(check_result, outlist2)
+})
+
+test_that("Detect only very large whole-number values but not fractional values", {
+  # Fractional values would be detected by checkLabeledFractionals
+  df2 <- recodeGADS(GADSdat = df1,
+                    varName = "VAR1",
+                    oldValues = c(1,-99),
+                    newValues = c(2147483648, -9999999999.99),
+                    existingMeta = "ignore")
+  check_result <- checkIntOverflow(GADSdat = df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", 2147483648, "valid", FALSE, 4)
+  expect_equal(check_result, outlist2)
+})
diff --git a/tests/testthat/test_checkLabeledFractionals.R b/tests/testthat/test_checkLabeledFractionals.R
new file mode 100644
index 00000000..8fb75fbd
--- /dev/null
+++ b/tests/testthat/test_checkLabeledFractionals.R
@@ -0,0 +1,65 @@
+# load + generally prepare data
+dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
+df1 <- changeValLabels(GADSdat = dfSAV,
+                       varName = "VAR1",
+                       value = 2,
+                       valLabel = "Apple")
+
+# general output structure to be changed for each test
+outlist <- data.frame(varName = character(),
+                      value = numeric(),
+                      missings = character(),
+                      empty = logical())
+
+test_that("Correctly identify metadata without labeled fractional values", {
+  check_result <- checkLabeledFractionals(GADSdat = df1)
+  expect_equal(check_result, outlist)
+})
+
+test_that("One existing labeled fractional in one variable", {
+  df2 <- suppressMessages(removeVars(GADSdat = df1,
+                                     vars = c("VAR2", "VAR3")))
+  df2 <- recodeGADS(GADSdat = df2,
+                    varName = "VAR1",
+                    oldValues = 1,
+                    newValues = .5,
+                    existingMeta = "ignore")
+  check_result <- checkLabeledFractionals(GADSdat = df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", .5, "valid", FALSE)
+  expect_equal(check_result, outlist2)
+})
+
+test_that("Only empty labeled fractionals", {
+  df2 <- changeValLabels(GADSdat = df1,
+                         varName = "VAR1",
+                         value = c(.2, -94.94),
+                         valLabel = c("point two", "mbd"))
+  df2 <- changeMissings(GADSdat = df2,
+                        varName = "VAR1",
+                        value = c(.2, -94.94),
+                        missings = c("valid", "miss"))
+  check_result <- checkLabeledFractionals(GADSdat = df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", -94.94, "miss", TRUE)
+  outlist2[2,] <- list("VAR1", .2, "valid", TRUE)
+  expect_equal(check_result, outlist2)
+})
+
+# remove this last one?
+test_that("Two labeled fractionals in the same variable where one value is empty", {
+  df2 <- recodeGADS(GADSdat = df1,
+                    varName = "VAR1",
+                    oldValues = 2,
+                    newValues = .5555555,
+                    existingMeta = "ignore")
+  df2 <- changeValLabels(GADSdat = df2,
+                         varName = "VAR1",
+                         value = .000001,
+                         valLabel = "nothing")
+  check_result <- checkLabeledFractionals(GADSdat = df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", .000001, "valid", TRUE)
+  outlist2[2,] <- list("VAR1", .5555555, "valid", FALSE)
+  expect_equal(check_result, outlist2)
+})


Reviews:
user: login: beckerbenj
body: Thanks for the PR, looks mostly great to me!

Two "bigger" requests (which we can also discuss if you disagree):
- In your tests, could you use argument names for all arguments beyond position 1 or 2? I have written these functions, but even for me this diminishes readability.
- Your current output for no reported labeled large values/fractionals is a `data.frame` with `nrow() = 1`. I see the benefits regarding the UI for users, but this is inconsistent with the existing reporting in `eatGADS` and `eatFDZ` and hinders the usage of these functions in other functions. For me, the two options would be possible: a) a data,frame with `nrow() = 0` or b) a single string "all ok" or similar. I would strongly prefer a).

Some other, more minor comments in the respective code. Thanks again and looking forward to more PRs!
state: CHANGES_REQUESTED
author_association: OWNER
submitted_at: 2025-05-16T14:53:31Z
user: login: weigtnik
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-21T12:18:38Z
user: login: weigtnik
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-21T13:07:44Z
user: login: weigtnik
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-21T13:45:01Z
user: login: beckerbenj
state: COMMENTED
author_association: OWNER
submitted_at: 2025-05-21T13:51:55Z
user: login: weigtnik
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-21T15:28:08Z
user: login: weigtnik
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-21T15:33:16Z
user: login: beckerbenj
state: COMMENTED
author_association: OWNER
submitted_at: 2025-05-21T15:49:47Z
user: login: beckerbenj
body: Thanks for the changes, looks all good to me!

Some minor nits in the respective comments. 

Feel free to merge (and delete the branch).
state: APPROVED
author_association: OWNER
submitted_at: 2025-05-26T12:20:47Z

Review comments:
diff_hunk: @@ -0,0 +1,73 @@
+#' Check a \code{GADSdat} for large integers.
+#'
+#' Check a \code{GADSdat} object for any occurrences of integer values, esp.
path: R/checkIntOverflow.R
user: login: beckerbenj
body: Could this maybe be made more specific? The function checks for large values which are labelled or tagged as missing, maybe the description could state this explicitly?

Conceptually, I think the description is a bit imprecise in using the terms `integer` or `integer values`. In my opinion, there are no/rarely any integers in a `GADSdat` object, as `haven`/`eatGADS` do not import variables as integers and the value column in a GADSdat meta data is `numeric/floating point`. From your description, issues arise when `haven` tries to transform these large numeric values to integer. Maybe this could be stated more explicitly?

Also note, that currently the function does not differentiate between values that could be called "integer values" and values that need floating point representation:

`df2 <- recodeGADS(df1, "VAR1", c(1,-99), c(2147483648.5, -2147483648.5), "ignore")`
created_at: 2025-05-16T14:20:53Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,73 @@
+#' Check a \code{GADSdat} for large integers.
+#'
+#' Check a \code{GADSdat} object for any occurrences of integer values, esp.
+#' in the metadata, that are too large for R to handle.
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
path: R/checkIntOverflow.R
user: login: beckerbenj
body: Is this a duplicated/alternative line?
created_at: 2025-05-16T14:21:08Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,73 @@
+#' Check a \code{GADSdat} for large integers.
+#'
+#' Check a \code{GADSdat} object for any occurrences of integer values, esp.
+#' in the metadata, that are too large for R to handle.
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
+#'
+#' According to its documentation, R can only handle \code{\link[base:integer]{integers}}
+#' of up to (roughly) \eqn{\pm 2 \times 10^9} (2,147,483,647 to be exact;
+#' c.f. \code{\link[base:.Machine]{.Machine}$integer.max}).
+#' This restriction appears to be relevant only when exporting a \code{GADSdat} to \code{.dta}
+#' and only when the very large value is also labeled (or tagged as missing).
+#' This is due to Stata only accepting labeled \emph{integer} values, not labeled \emph{double}
+#' values. Unlabeled values will stay a generic numeric.
+#'
+#'@param GADSdat A \code{GADSdat} object.
+#'
+#'@return Returns a \code{data.frame}, listing the affected \code{varName}s,
+#' the large \code{value}s, and their respective \code{missings} tag
+#' according to the metadata, as well as whether they actually occur in the data  (\code{empty}).
+#' The \code{rownum}s of the affected rows in \code{GADSdat$labels} are provided
+#' in a separate column as a fail safe, too.
+#'
+#'@examples
+#' # Introduce a fractional value into meta data
+#' pisa2 <- changeMissings(GADSdat = pisa,
+#'                         varName = "schtype",
+#'                         value = 9999999999,
+#'                         missings = "miss")
+#' checkIntOverflow(pisa2)
+#'
+#'@export
+checkIntOverflow <- function(GADSdat) {
+  check_GADSdat(GADSdat)
+  labels <- GADSdat$labels
+
+  out <- data.frame(varName = "<none found>",
+                    value = NA_real_,
+                    missings = NA_character_,
+                    empty = NA,
+                    rownum = NA_integer_)
+
+  # option 1
+  # huge_number_rows <- which((labels$labeled == "yes") &
+  #                            (labels$value > 2147483647 | labels$value < -2147483647))
+
+  # option 2
+  huge_number_rows <- suppressWarnings(which((labels$labeled == "yes") &
+                                               !is.na(as.numeric(labels$value)) &
+                                               is.na(as.integer(labels$value))))
+
+  if (length(huge_number_rows) == 0) {
+    return(out)
+  }
+
+  out[1:length(huge_number_rows), 1:3] <- labels[huge_number_rows, c("varName",
path: R/checkIntOverflow.R
user: login: beckerbenj
body: For increased readability, could you use column names instead of numbers within `out`?
created_at: 2025-05-16T14:30:03Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,73 @@
+#' Check a \code{GADSdat} for large integers.
+#'
+#' Check a \code{GADSdat} object for any occurrences of integer values, esp.
+#' in the metadata, that are too large for R to handle.
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
+#'
+#' According to its documentation, R can only handle \code{\link[base:integer]{integers}}
+#' of up to (roughly) \eqn{\pm 2 \times 10^9} (2,147,483,647 to be exact;
+#' c.f. \code{\link[base:.Machine]{.Machine}$integer.max}).
+#' This restriction appears to be relevant only when exporting a \code{GADSdat} to \code{.dta}
+#' and only when the very large value is also labeled (or tagged as missing).
+#' This is due to Stata only accepting labeled \emph{integer} values, not labeled \emph{double}
+#' values. Unlabeled values will stay a generic numeric.
+#'
+#'@param GADSdat A \code{GADSdat} object.
+#'
+#'@return Returns a \code{data.frame}, listing the affected \code{varName}s,
+#' the large \code{value}s, and their respective \code{missings} tag
+#' according to the metadata, as well as whether they actually occur in the data  (\code{empty}).
+#' The \code{rownum}s of the affected rows in \code{GADSdat$labels} are provided
+#' in a separate column as a fail safe, too.
+#'
+#'@examples
+#' # Introduce a fractional value into meta data
+#' pisa2 <- changeMissings(GADSdat = pisa,
+#'                         varName = "schtype",
+#'                         value = 9999999999,
+#'                         missings = "miss")
+#' checkIntOverflow(pisa2)
+#'
+#'@export
+checkIntOverflow <- function(GADSdat) {
+  check_GADSdat(GADSdat)
+  labels <- GADSdat$labels
+
+  out <- data.frame(varName = "<none found>",
+                    value = NA_real_,
+                    missings = NA_character_,
+                    empty = NA,
+                    rownum = NA_integer_)
+
+  # option 1
+  # huge_number_rows <- which((labels$labeled == "yes") &
+  #                            (labels$value > 2147483647 | labels$value < -2147483647))
+
+  # option 2
+  huge_number_rows <- suppressWarnings(which((labels$labeled == "yes") &
+                                               !is.na(as.numeric(labels$value)) &
+                                               is.na(as.integer(labels$value))))
+
+  if (length(huge_number_rows) == 0) {
+    return(out)
+  }
+
+  out[1:length(huge_number_rows), 1:3] <- labels[huge_number_rows, c("varName",
+                                                                     "value",
+                                                                     "missings")]
+  out$rownum <- huge_number_rows
+
+  varlist <- unique(out$varName)
+  empty_values <- checkEmptyValLabels(GADSdat = GADSdat,
+                                      vars = varlist)
+  out$empty <- unlist(lapply(varlist, function(varname) {
path: R/checkIntOverflow.R
user: login: beckerbenj
body: Would this maybe be simpler/more readable?

```
  for(varname in varlist) {
    vallist <- out[out$varName == varname, "value"]
    out$empty <- vallist %in% empty_values[[varname]]$value
  }
```
created_at: 2025-05-16T14:39:23Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,58 @@
+#' Check meta data for fractional values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of fractional values
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
path: R/checkLabeledFractionals.R
user: login: beckerbenj
body: Could 
> which could cause problems esp. when exporting into \code{.dta} format.

be removed from this paragraph and given a separate paragraph in details?
created_at: 2025-05-16T14:40:54Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,58 @@
+#' Check meta data for fractional values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of fractional values
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
+#'
+#' This functions checks values that are tagged as labeled in the corresponding
+#' metadata column (\code{GADSdat$labels$labeled}). It therefore covers both
+#' "truely" labeled values (that have been assigned a \code{valLabel}) and
+#' values tagged as \code{missings} (with or without a \code{valLabel}).
+#'
+#'@param GADSdat A \code{GADSdat} object.
+#'
+#'@return Returns a \code{data.frame}, listing the affected \code{varName}s,
+#' the labeled fractional \code{value}s, and their respective \code{missings} tag
+#' according to the metadata, as well as whether they actually occur in the data (\code{empty}).
+#'
+#'@examples
+#' # Introduce a fractional value into meta data
+#' pisa2 <- recodeGADS(GADSdat = pisa,
+#'                     varName = "schtype",
+#'                     oldValues = 2,
+#'                     newValues = .5)
+#' checkLabeledFractionals(pisa2)
+#'
+#'@export
+checkLabeledFractionals <- function(GADSdat) {
+  check_GADSdat(GADSdat)
+  labels <- GADSdat$labels
+
+  out <- data.frame(varName = "<none found>",
+                    value = NA_real_,
+                    missings = NA_character_,
+                    empty = NA)
+
+  labeled_fractional_rows <- which((labels$labeled == "yes") & (labels$value %% 1 != 0))
path: R/checkLabeledFractionals.R
user: login: beckerbenj
body: The labeled column is a bit tricky. It is barely used within `eatGADS` and I am not sure whether it is wise to rely on it. Maybe it would make sense to test for `!is.na(labels$value)` instead?
created_at: 2025-05-16T14:43:12Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,58 @@
+#' Check meta data for fractional values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of fractional values
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
+#'
+#' This functions checks values that are tagged as labeled in the corresponding
+#' metadata column (\code{GADSdat$labels$labeled}). It therefore covers both
+#' "truely" labeled values (that have been assigned a \code{valLabel}) and
+#' values tagged as \code{missings} (with or without a \code{valLabel}).
+#'
+#'@param GADSdat A \code{GADSdat} object.
+#'
+#'@return Returns a \code{data.frame}, listing the affected \code{varName}s,
+#' the labeled fractional \code{value}s, and their respective \code{missings} tag
+#' according to the metadata, as well as whether they actually occur in the data (\code{empty}).
+#'
+#'@examples
+#' # Introduce a fractional value into meta data
+#' pisa2 <- recodeGADS(GADSdat = pisa,
+#'                     varName = "schtype",
+#'                     oldValues = 2,
+#'                     newValues = .5)
+#' checkLabeledFractionals(pisa2)
+#'
+#'@export
+checkLabeledFractionals <- function(GADSdat) {
+  check_GADSdat(GADSdat)
+  labels <- GADSdat$labels
+
+  out <- data.frame(varName = "<none found>",
+                    value = NA_real_,
+                    missings = NA_character_,
+                    empty = NA)
+
+  labeled_fractional_rows <- which((labels$labeled == "yes") & (labels$value %% 1 != 0))
+
+  if (length(labeled_fractional_rows) == 0) {
+    return(out)
+  }
+
+  out[1:length(labeled_fractional_rows), 1:3] <- labels[labeled_fractional_rows, c("varName",
+                                                                                   "value",
+                                                                                   "missings")]
+
+  varlist <- unique(out$varName)
+  empty_values <- checkEmptyValLabels(GADSdat = GADSdat,
+                                      vars = varlist)
+  out$empty <- unlist(lapply(varlist, function(varname) {
path: R/checkLabeledFractionals.R
user: login: beckerbenj
body: see comment above
created_at: 2025-05-16T14:43:24Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,45 @@
+# load + generally prepare data
+dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
+df1 <- changeValLabels(dfSAV, "VAR1", 2, "Apple")
+
+# general output structure to be changed for each test
+outlist <- data.frame(varName = "<none found>",
+                      value = NA_real_,
+                      missings = NA_character_,
+                      empty = NA,
+                      rownum = NA_integer_)
+
+test_that("Correctly identify metadata without very large labeled values", {
path: tests/testthat/test_checkIntOverflow.R
user: login: beckerbenj
body: LGTM
created_at: 2025-05-16T14:43:54Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,45 @@
+# load + generally prepare data
+dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
+df1 <- changeValLabels(dfSAV, "VAR1", 2, "Apple")
+
+# general output structure to be changed for each test
+outlist <- data.frame(varName = "<none found>",
+                      value = NA_real_,
+                      missings = NA_character_,
+                      empty = NA,
+                      rownum = NA_integer_)
+
+test_that("Correctly identify metadata without very large labeled values", {
+  check_result <- checkIntOverflow(df1)
+  expect_equal(check_result, outlist)
+})
+
+test_that("Two existing labeled value exactly 1 above/below the limit in one variable", {
path: tests/testthat/test_checkIntOverflow.R
user: login: beckerbenj
body: LGTM
created_at: 2025-05-16T14:44:17Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,45 @@
+# load + generally prepare data
+dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
+df1 <- changeValLabels(dfSAV, "VAR1", 2, "Apple")
+
+# general output structure to be changed for each test
+outlist <- data.frame(varName = "<none found>",
+                      value = NA_real_,
+                      missings = NA_character_,
+                      empty = NA,
+                      rownum = NA_integer_)
+
+test_that("Correctly identify metadata without very large labeled values", {
+  check_result <- checkIntOverflow(df1)
+  expect_equal(check_result, outlist)
+})
+
+test_that("Two existing labeled value exactly 1 above/below the limit in one variable", {
+  df2 <- recodeGADS(df1, "VAR1", c(1,-99), c(2147483648, -2147483648), "ignore")
+  check_result <- checkIntOverflow(df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", -2147483648, "miss", FALSE, 1)
+  outlist2[2,] <- list("VAR1", 2147483648, "valid", FALSE, 4)
+  expect_equal(check_result, outlist2)
+})
+
+test_that("Only empty very large labeled values", {
path: tests/testthat/test_checkIntOverflow.R
user: login: beckerbenj
body: LGTM
created_at: 2025-05-16T14:44:38Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,45 @@
+# load + generally prepare data
+dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
+df1 <- changeValLabels(dfSAV, "VAR1", 2, "Apple")
+
+# general output structure to be changed for each test
+outlist <- data.frame(varName = "<none found>",
+                      value = NA_real_,
+                      missings = NA_character_,
+                      empty = NA,
+                      rownum = NA_integer_)
+
+test_that("Correctly identify metadata without very large labeled values", {
+  check_result <- checkIntOverflow(df1)
+  expect_equal(check_result, outlist)
+})
+
+test_that("Two existing labeled value exactly 1 above/below the limit in one variable", {
+  df2 <- recodeGADS(df1, "VAR1", c(1,-99), c(2147483648, -2147483648), "ignore")
+  check_result <- checkIntOverflow(df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", -2147483648, "miss", FALSE, 1)
+  outlist2[2,] <- list("VAR1", 2147483648, "valid", FALSE, 4)
+  expect_equal(check_result, outlist2)
+})
+
+test_that("Only empty very large labeled values", {
+  df2 <- changeValLabels(df1, "VAR1", c(-9999999999, 9999999999), c("mbddd", "other"))
+  df2 <- changeMissings(df2, "VAR1", c(-9999999999, 9999999999), c("miss", "valid"))
+  check_result <- checkIntOverflow(df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", -9999999999, "miss", TRUE, 1)
+  outlist2[2,] <- list("VAR1", 9999999999, "valid", TRUE, 6)
+  expect_equal(check_result, outlist2)
+})
+
+# remove this last one?
+test_that("Two very large labeled values in the same variable where one value is empty", {
path: tests/testthat/test_checkIntOverflow.R
user: login: beckerbenj
body: Maybe instead you could add a test where there are no "empty" value labels at all in a variable?
created_at: 2025-05-16T14:45:18Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,43 @@
+# load + generally prepare data
+dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
+df1 <- changeValLabels(dfSAV, "VAR1", 2, "Apple")
+
+# general output structure to be changed for each test
+outlist <- data.frame(varName = "<none found>",
+                      value = NA_real_,
+                      missings = NA_character_,
+                      empty = NA)
+
+test_that("Correctly identify metadata without labeled fractional values", {
path: tests/testthat/test_checkLabeledFractionals.R
user: login: beckerbenj
body: LGTM
created_at: 2025-05-16T14:46:03Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,43 @@
+# load + generally prepare data
+dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
+df1 <- changeValLabels(dfSAV, "VAR1", 2, "Apple")
+
+# general output structure to be changed for each test
+outlist <- data.frame(varName = "<none found>",
+                      value = NA_real_,
+                      missings = NA_character_,
+                      empty = NA)
+
+test_that("Correctly identify metadata without labeled fractional values", {
+  check_result <- checkLabeledFractionals(df1)
+  expect_equal(check_result, outlist)
+})
+
+test_that("One existing labeled fractional in one variable", {
path: tests/testthat/test_checkLabeledFractionals.R
user: login: beckerbenj
body: LGTM
created_at: 2025-05-16T14:46:09Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,43 @@
+# load + generally prepare data
+dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
+df1 <- changeValLabels(dfSAV, "VAR1", 2, "Apple")
+
+# general output structure to be changed for each test
+outlist <- data.frame(varName = "<none found>",
+                      value = NA_real_,
+                      missings = NA_character_,
+                      empty = NA)
+
+test_that("Correctly identify metadata without labeled fractional values", {
+  check_result <- checkLabeledFractionals(df1)
+  expect_equal(check_result, outlist)
+})
+
+test_that("One existing labeled fractional in one variable", {
+  df2 <- recodeGADS(df1, "VAR1", 1, .5, "ignore")
+  check_result <- checkLabeledFractionals(df2)
+  outlist2 <- outlist
+  outlist2[1,] <- list("VAR1", .5, "valid", FALSE)
+  expect_equal(check_result, outlist2)
+})
+
+test_that("Only empty labeled fractionals", {
path: tests/testthat/test_checkLabeledFractionals.R
user: login: beckerbenj
body: LGTM
created_at: 2025-05-16T14:46:48Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,73 @@
+#' Check a \code{GADSdat} for large integers.
+#'
+#' Check a \code{GADSdat} object for any occurrences of integer values, esp.
path: R/checkIntOverflow.R
user: login: weigtnik
body: Thanks for your comment and your input! I have changed the wording to "whole-number values" for the "`GADSdat` side" of affairs, and also tried to explain the issue a bit more. I'm looking forward to your feedback on the changes!

Also, thanks for spotting the oversight regarding large floating-point/fractional values! I have fixed that and added a corresponding test.
created_at: 2025-05-21T12:18:37Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,73 @@
+#' Check a \code{GADSdat} for large integers.
+#'
+#' Check a \code{GADSdat} object for any occurrences of integer values, esp.
+#' in the metadata, that are too large for R to handle.
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
+#'
+#' According to its documentation, R can only handle \code{\link[base:integer]{integers}}
+#' of up to (roughly) \eqn{\pm 2 \times 10^9} (2,147,483,647 to be exact;
+#' c.f. \code{\link[base:.Machine]{.Machine}$integer.max}).
+#' This restriction appears to be relevant only when exporting a \code{GADSdat} to \code{.dta}
+#' and only when the very large value is also labeled (or tagged as missing).
+#' This is due to Stata only accepting labeled \emph{integer} values, not labeled \emph{double}
+#' values. Unlabeled values will stay a generic numeric.
+#'
+#'@param GADSdat A \code{GADSdat} object.
+#'
+#'@return Returns a \code{data.frame}, listing the affected \code{varName}s,
+#' the large \code{value}s, and their respective \code{missings} tag
+#' according to the metadata, as well as whether they actually occur in the data  (\code{empty}).
+#' The \code{rownum}s of the affected rows in \code{GADSdat$labels} are provided
+#' in a separate column as a fail safe, too.
+#'
+#'@examples
+#' # Introduce a fractional value into meta data
+#' pisa2 <- changeMissings(GADSdat = pisa,
+#'                         varName = "schtype",
+#'                         value = 9999999999,
+#'                         missings = "miss")
+#' checkIntOverflow(pisa2)
+#'
+#'@export
+checkIntOverflow <- function(GADSdat) {
+  check_GADSdat(GADSdat)
+  labels <- GADSdat$labels
+
+  out <- data.frame(varName = "<none found>",
+                    value = NA_real_,
+                    missings = NA_character_,
+                    empty = NA,
+                    rownum = NA_integer_)
+
+  # option 1
+  # huge_number_rows <- which((labels$labeled == "yes") &
+  #                            (labels$value > 2147483647 | labels$value < -2147483647))
+
+  # option 2
+  huge_number_rows <- suppressWarnings(which((labels$labeled == "yes") &
+                                               !is.na(as.numeric(labels$value)) &
+                                               is.na(as.integer(labels$value))))
+
+  if (length(huge_number_rows) == 0) {
+    return(out)
+  }
+
+  out[1:length(huge_number_rows), 1:3] <- labels[huge_number_rows, c("varName",
+                                                                     "value",
+                                                                     "missings")]
+  out$rownum <- huge_number_rows
+
+  varlist <- unique(out$varName)
+  empty_values <- checkEmptyValLabels(GADSdat = GADSdat,
+                                      vars = varlist)
+  out$empty <- unlist(lapply(varlist, function(varname) {
path: R/checkIntOverflow.R
user: login: weigtnik
body: Yes, that seems like a more elegant/simple solution, thanks!
created_at: 2025-05-21T13:07:44Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,58 @@
+#' Check meta data for fractional values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of fractional values
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
path: R/checkLabeledFractionals.R
user: login: weigtnik
body: I thought that the description would then be too redundant with the title of the page. But I think I get why this (in terms of manual page sections) is more of a detail than a general description - and especially why a more detailed elaboration would be in order.
created_at: 2025-05-21T13:45:00Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,58 @@
+#' Check meta data for fractional values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of fractional values
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
path: R/checkLabeledFractionals.R
user: login: beckerbenj
body: I understand the feeling of redundancy. See, e.g., here for some guidelines (which often enough I myself do not follow...):
https://r-pkgs.org/man.html#description
created_at: 2025-05-21T13:51:55Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,58 @@
+#' Check meta data for fractional values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of fractional values
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
+#'
+#' This functions checks values that are tagged as labeled in the corresponding
+#' metadata column (\code{GADSdat$labels$labeled}). It therefore covers both
+#' "truely" labeled values (that have been assigned a \code{valLabel}) and
+#' values tagged as \code{missings} (with or without a \code{valLabel}).
+#'
+#'@param GADSdat A \code{GADSdat} object.
+#'
+#'@return Returns a \code{data.frame}, listing the affected \code{varName}s,
+#' the labeled fractional \code{value}s, and their respective \code{missings} tag
+#' according to the metadata, as well as whether they actually occur in the data (\code{empty}).
+#'
+#'@examples
+#' # Introduce a fractional value into meta data
+#' pisa2 <- recodeGADS(GADSdat = pisa,
+#'                     varName = "schtype",
+#'                     oldValues = 2,
+#'                     newValues = .5)
+#' checkLabeledFractionals(pisa2)
+#'
+#'@export
+checkLabeledFractionals <- function(GADSdat) {
+  check_GADSdat(GADSdat)
+  labels <- GADSdat$labels
+
+  out <- data.frame(varName = "<none found>",
+                    value = NA_real_,
+                    missings = NA_character_,
+                    empty = NA)
+
+  labeled_fractional_rows <- which((labels$labeled == "yes") & (labels$value %% 1 != 0))
path: R/checkLabeledFractionals.R
user: login: weigtnik
body: Thanks for your comment! Working on another above, I realized that I don't really need to look at that column - and I don't know why I did, anymore. Any value in `GADSdat$labels` is relevant to this function, and `labeled` does not really add any information to that.

Somewhat related, I was now also wondering: Should `write_stata` have a `convertMiss` argument and functionality like `extractData2` and its precursor do? `haven` is not (yet?) able to convert individual missing codes, anyway. So it would save a bit of time to convert all of them right away, if one chooses to.
created_at: 2025-05-21T15:28:08Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,58 @@
+#' Check meta data for fractional values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of fractional values
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
path: R/checkLabeledFractionals.R
user: login: weigtnik
body: Thanks for the resource! I think "[just] Try to find a slightly different wording" is a good instruction for me. 👍
created_at: 2025-05-21T15:33:16Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,58 @@
+#' Check meta data for fractional values.
+#'
+#' Check a \code{GADSdat} object for any occurrences of fractional values
+#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
+#'
+#' This functions checks values that are tagged as labeled in the corresponding
+#' metadata column (\code{GADSdat$labels$labeled}). It therefore covers both
+#' "truely" labeled values (that have been assigned a \code{valLabel}) and
+#' values tagged as \code{missings} (with or without a \code{valLabel}).
+#'
+#'@param GADSdat A \code{GADSdat} object.
+#'
+#'@return Returns a \code{data.frame}, listing the affected \code{varName}s,
+#' the labeled fractional \code{value}s, and their respective \code{missings} tag
+#' according to the metadata, as well as whether they actually occur in the data (\code{empty}).
+#'
+#'@examples
+#' # Introduce a fractional value into meta data
+#' pisa2 <- recodeGADS(GADSdat = pisa,
+#'                     varName = "schtype",
+#'                     oldValues = 2,
+#'                     newValues = .5)
+#' checkLabeledFractionals(pisa2)
+#'
+#'@export
+checkLabeledFractionals <- function(GADSdat) {
+  check_GADSdat(GADSdat)
+  labels <- GADSdat$labels
+
+  out <- data.frame(varName = "<none found>",
+                    value = NA_real_,
+                    missings = NA_character_,
+                    empty = NA)
+
+  labeled_fractional_rows <- which((labels$labeled == "yes") & (labels$value %% 1 != 0))
path: R/checkLabeledFractionals.R
user: login: beckerbenj
body: > Somewhat related, I was now also wondering: Should write_stata have a convertMiss argument and functionality like extractData2 and its precursor do? haven is not (yet?) able to convert individual missing codes, anyway. So it would save a bit of time to convert all of them right away, if one chooses to.

I see the utility in this. From my perspective, this would be an additional feature on what is currently planned for `checkStata()`/`write_stata()`. Feel free to open a new issue!
created_at: 2025-05-21T15:49:46Z
author_association: OWNER
diff_hunk: @@ -1,24 +1,26 @@
-#' Check a \code{GADSdat} for large integers.
+#' Check a \code{GADSdat} for large labeled whole-number values.
 #'
-#' Check a \code{GADSdat} object for any occurrences of integer values, esp.
-#' in the metadata, that are too large for R to handle.
-#' in its meta data which could cause problems esp. when exporting into \code{.dta} format.
+#' Check a \code{GADSdat} object for any occurrences of labeled whole-number values
+#'  that would be too large for R to handle if they were coerced \code{as.integer()}.
 #'
-#' According to its documentation, R can only handle \code{\link[base:integer]{integers}}
-#' of up to (roughly) \eqn{\pm 2 \times 10^9} (2,147,483,647 to be exact;
+#' According to its documentation, R can only handle \code{\link[base:integer]{integer}}
+#' values of up to (roughly) \eqn{\pm 2 \times 10^9} (2,147,483,647 to be exact;
 #' c.f. \code{\link[base:.Machine]{.Machine}$integer.max}).
-#' This restriction appears to be relevant only when exporting a \code{GADSdat} to \code{.dta}
-#' and only when the very large value is also labeled (or tagged as missing).
-#' This is due to Stata only accepting labeled \emph{integer} values, not labeled \emph{double}
-#' values. Unlabeled values will stay a generic numeric.
+#' This restriction is only relevant when exporting a \code{GADSdat} to \code{.dta}
path: R/checkIntOverflow.R
user: login: beckerbenj
body: Nit: 
Can you remove `only` from the sentence? I would try to avoid using global statements that may change in the future somewhere else in the package.
created_at: 2025-05-23T09:01:13Z
author_association: OWNER
diff_hunk: @@ -33,40 +35,34 @@ checkIntOverflow <- function(GADSdat) {
   check_GADSdat(GADSdat)
   labels <- GADSdat$labels
 
-  out <- data.frame(varName = "<none found>",
+  out <- data.frame(varName = NA_character_,
                     value = NA_real_,
                     missings = NA_character_,
                     empty = NA,
-                    rownum = NA_integer_)
+                    rownum = NA_integer_)[0,]
 
-  # option 1
-  # huge_number_rows <- which((labels$labeled == "yes") &
-  #                            (labels$value > 2147483647 | labels$value < -2147483647))
+  huge_labeled_number_rows <- which(abs(labels$value) > .Machine$integer.max &
path: R/checkIntOverflow.R
user: login: beckerbenj
body: LGTM!
created_at: 2025-05-26T12:13:11Z
author_association: OWNER
diff_hunk: @@ -33,40 +35,34 @@ checkIntOverflow <- function(GADSdat) {
   check_GADSdat(GADSdat)
   labels <- GADSdat$labels
 
-  out <- data.frame(varName = "<none found>",
+  out <- data.frame(varName = NA_character_,
path: R/checkIntOverflow.R
user: login: beckerbenj
body: Nit:

Could you change this to use empty vectors in the first place? 
```
data.frame(varName = character(),
                   value = numeric(), ....)
```
and omit the subsetting `[0,]`
created_at: 2025-05-26T12:16:34Z
author_association: OWNER
diff_hunk: @@ -27,31 +29,31 @@ checkLabeledFractionals <- function(GADSdat) {
   check_GADSdat(GADSdat)
   labels <- GADSdat$labels
 
-  out <- data.frame(varName = "<none found>",
+  out <- data.frame(varName = NA_character_,
path: R/checkLabeledFractionals.R
user: login: beckerbenj
body: See above
created_at: 2025-05-26T12:18:04Z
author_association: OWNER
diff_hunk: @@ -1,45 +1,73 @@
 # load + generally prepare data
 dfSAV <- import_spss(file = test_path("helper_spss_missings.sav"))
-df1 <- changeValLabels(dfSAV, "VAR1", 2, "Apple")
+df1 <- changeValLabels(GADSdat = dfSAV,
+                       varName = "VAR1",
+                       value = 2,
+                       valLabel = "Apple")
 
 # general output structure to be changed for each test
-outlist <- data.frame(varName = "<none found>",
+outlist <- data.frame(varName = NA_character_,
path: tests/testthat/test_checkIntOverflow.R
user: login: beckerbenj
body: see above
created_at: 2025-05-26T12:18:37Z
author_association: OWNER

PR comments:
user: login: weigtnik
created_at: 2025-05-19T16:11:07Z
body: Thanks for your thorough review and your comments! I will try to address them over the course of this week. 🙌
author_association: COLLABORATOR
user: login: weigtnik
created_at: 2025-05-19T16:54:40Z
body: Regarding your (somewhat) major/general requests:

1. I absolutely agree, and in hindsight, I don't even understand why I left out the argument names in the tests.
2. Thanks for bringing up the output/return format! The first option you described sounds preferable to me, too. I have now been thinking about a `verbose` option to get a message saying "all good". But I don't think that's a very useful addition to the function.
author_association: COLLABORATOR