-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: NPI Constructor #62
Comments
Function
construct_npi <- function(npi) {
npi_test <- provider:::validate_npi(npi, print = TRUE)
#---
cli_npi <- rlang::sym(npi_test)
cli::cli_alert("Testing NPI: {.strong {.val {cli_npi}}}")
#---
# Remove the 10th digit to create the 9-position identifier part of the NPI
id_9 <- unlist(strsplit(npi_test, ""), use.names = FALSE)[1:9]
#---
cli_id_9 <- rlang::sym(paste0(c(id_9, "_"), collapse = ""))
cli::cli_alert("Keep first 9 digits: {.strong {.val {cli_id_9}}}")
#---
# Reverse order of digits
x_rev <- rev(id_9)
#---
cli_x_rev <- rlang::sym(paste0(x_rev, collapse = ""))
cli::cli_alert("Reverse digit order: {.strong {.val {cli_x_rev}}}")
#---
# Select index of every other digit
x_idx <- seq(1, length(x_rev), 2)
#---
cli_x_idx <- rlang::sym(paste0(x_rev[x_idx], collapse = " "))
cli::cli_alert("Select every other digit: {.strong {.val {cli_x_idx}}}")
#---
# Double the value of the alternate digits
x_rev[x_idx] <- as.numeric(x_rev[x_idx]) * 2
#---
cli_dbl <- rlang::sym(paste0(x_rev[x_idx], collapse = " "))
cli_ins <- rlang::sym(paste0(x_rev, collapse = " "))
cli::cli_alert("Double each: {.strong {.val {cli_dbl}}}")
cli::cli_alert("Replace original with doubles: {.strong {.val {cli_ins}}}")
#---
# Split and unlist to separate digits
x_split <- unlist(strsplit(x_rev, ""), use.names = FALSE)
x_add <- sum(as.numeric(x_split))
#---
cli_x_add <- rlang::sym(paste0(paste0(x_split, collapse = " + "), paste0(" = ", x_add)))
cli::cli_alert("Sum individual digits: {.strong {.val {cli_x_add}}}")
#---
# Add constant 24 to the sum of the digits
x_24 <- x_add + 24
#---
sym_24 <- rlang::sym("24")
cli_x_24 <- rlang::sym(paste0(paste0(c(x_add, 24), collapse = " + "), paste0(" = ", x_24)))
cli::cli_alert("Add {.strong {.val {sym_24}}} to the sum: {.strong {.val {cli_x_24}}}")
#---
x_divide <- x_24 / 10
cli_x_divide <- rlang::sym(paste0(paste0(x_24, " / ", 10), paste0(" = ", x_divide)))
cli::cli_alert("Divide by 10: {.strong {.val {cli_x_divide}}}")
x_divide_first <- as.numeric(unlist(strsplit(as.character(x_divide), ""), use.names = FALSE)[1])
cli_x_first <- rlang::sym(paste0(paste0(x_divide), paste0(" = ", x_divide_first)))
cli::cli_alert("Take first digit: {.strong {.val {cli_x_first}}}")
x_plus_one <- x_divide_first + 1
cli_x_plus <- rlang::sym(paste0(paste0(x_divide_first, " + ", 1), paste0(" = ", x_plus_one)))
cli::cli_alert("Add one: {.strong {.val {cli_x_plus}}}")
x_paste_zero <- paste0(x_plus_one, "0")
cli_x_zero <- rlang::sym(paste0(paste0(x_plus_one, " * ", 10), paste0(" = ", x_paste_zero)))
cli::cli_alert("Multiply by 10: {.strong {.val {cli_x_zero}}}")
# Find the next higher number ending in zero
x_next <- ceiling(x_24 / 10) * 10
#---
cli_x_next <- rlang::sym(paste0(paste0("⌈", x_24,"⌉"), paste0(" = " , x_next)))
cli::cli_alert("This is the next largest integer divisible by 10: {.strong {.val {cli_x_next}}}")
#---
# Find the check digit by subtracting x from y
x_check <- x_next - x_24
#---
cli_x_check <- rlang::sym(paste0(paste0(c(x_next, x_24), collapse = " - "), paste0(" = ", x_check)))
cli::cli_alert(c("Find the check digit: {.strong {.val {cli_x_check}}}"))
#---
# Append the check digit to the end of the 9-digit identifier
id_10 <- id_9
id_10[10] <- x_check
#---
cli_id_10 <- rlang::sym(paste0(id_10, collapse = ""))
cli::cli_alert(c("Append check digit to the original value: {.strong {.val {cli_id_10}}}"))
#---
# Collapse the vector into a single string
npi_valid <- paste0(id_10, collapse = "")
# Is the syntactically valid NPI identical to the test NPI?
if (identical(npi_valid, npi_test)) {
#---
identical <- rlang::sym(paste0(c(npi_test, npi_valid), collapse = " = "))
cli::cli_alert_success(c("NPI {.strong is} syntactically valid: {.strong {.val {identical}}}"))
#---
}
if (!identical(npi_valid, npi_test)) {
#---
not_identical <- rlang::sym(paste0(c(npi_test, npi_valid), collapse = " != "))
cli::cli_alert_danger(c("NPI {.strong is not} syntactically valid: {.strong {.val {not_identical}}}"))
#---
}
} construct_npi(1234567891)
→ Testing NPI: 1234567891
→ Keep first 9 digits: 123456789_
→ Reverse digit order: 987654321
→ Select every other digit: 9 7 5 3 1
→ Double each: 18 14 10 6 2
→ Replace original with doubles: 18 8 14 6 10 4 6 2 2
→ Sum individual digits: 1 + 8 + 8 + 1 + 4 + 6 + 1 + 0 + 4 + 6 + 2 + 2 = 43
→ Add 24 to the sum: 43 + 24 = 67
→ Divide by 10: 67 / 10 = 6.7
→ Take first digit: 6.7 = 6
→ Add one: 6 + 1 = 7
→ Multiply by 10: 7 * 10 = 70
→ This is the next largest integer divisible by 10: ⌈67⌉ = 70
→ Find the check digit: 70 - 67 = 3
→ Append check digit to the original value: 1234567893
✖ NPI is not syntactically valid: 1234567891 != 1234567893
construct_npi(1043477615)
→ Testing NPI: 1043477615
→ Keep first 9 digits: 104347761_
→ Reverse digit order: 167743401
→ Select every other digit: 1 7 4 4 1
→ Double each: 2 14 8 8 2
→ Replace original with doubles: 2 6 14 7 8 3 8 0 2
→ Sum individual digits: 2 + 6 + 1 + 4 + 7 + 8 + 3 + 8 + 0 + 2 = 41
→ Add 24 to the sum: 41 + 24 = 65
→ Divide by 10: 65 / 10 = 6.5
→ Take first digit: 6.5 = 6
→ Add one: 6 + 1 = 7
→ Multiply by 10: 7 * 10 = 70
→ This is the next largest integer divisible by 10: ⌈65⌉ = 70
→ Find the check digit: 70 - 65 = 5
→ Append check digit to the original value: 1043477615
✔ NPI is syntactically valid: 1043477615 = 1043477615
construct_npi("0000000000")
→ Testing NPI: 0000000000
→ Keep first 9 digits: 000000000_
→ Reverse digit order: 000000000
→ Select every other digit: 0 0 0 0 0
→ Double each: 0 0 0 0 0
→ Replace original with doubles: 0 0 0 0 0 0 0 0 0
→ Sum individual digits: 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = 0
→ Add 24 to the sum: 0 + 24 = 24
→ Divide by 10: 24 / 10 = 2.4
→ Take first digit: 2.4 = 2
→ Add one: 2 + 1 = 3
→ Multiply by 10: 3 * 10 = 30
→ This is the next largest integer divisible by 10: ⌈24⌉ = 30
→ Find the check digit: 30 - 24 = 6
→ Append check digit to the original value: 0000000006
✖ NPI is not syntactically valid: 0000000000 != 0000000006 Created on 2023-12-03 with reprex v2.0.2 |
luhn <- function(x) {
x <- rev(as.integer(unlist(strsplit(x, ""))))
idx_odd <- seq_along(x) %% 2 == 1
idx_even <- seq_along(x) %% 2 == 0
x[idx_even] <- x[idx_even] * 2
x[idx_even] <- ifelse(x[idx_even] > 9, x[idx_even] - 9, x[idx_even])
sum_odd <- sum(x[idx_odd])
sum_even <- sum(x[idx_even])
sum_x <- sum_odd + sum_even
sum_x %% 10 == 0
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
NPI Constructor
Function
Examples:
Created on 2023-11-23 with reprex v2.0.2
The text was updated successfully, but these errors were encountered: