Search code examples
rdifflogical-operatorsdigit

logical check of vector values at the same precesion or not


I have a vector with variable elements in it, and I want to check whether it's last two element are in the same digit order.

For example, if the last two vectors are 0.0194 and 0.0198 return TRUE. because their digit order after zero is the same (0.01 order 10^-2). ! for other example the number could be 0.00014 and 0.00012 so their precision is still around the same the function should return also TRUE.

How can we build a logical statement or function to check this.

x<- c(0.817104, 0.241665, 0.040581, 0.022903, 0.019478, 0.019846)

Solution

  • I may be over-thinking this, but you can test that the order of magnitude and first non-zero digit are identical for each.

    x <- c(0.817104, 0.241665, 0.040581, 0.022903, 0.019478, 0.019846)
    
    oom <- function(x, base = 10) as.integer(ifelse(x == 0, 0, floor(log(abs(x), base))))
    oom(x)
    # [1] -1 -1 -2 -2 -2 -2
    
    (tr <- trunc(x / 10 ** oom(x, 10)))
    # [1] 8 2 4 2 1 1
    

    So for the last two, the order of magnitude for both is -2 and the first non-zero digit is 1 for both.

    Put into a function:

    f <- function(x) {
      oom <- function(x, base = 10) as.integer(ifelse(x == 0, 0, floor(log(abs(x), base))))
      x <- tail(x, 2)
      oo <- oom(x)
      tr <- trunc(x / 10 ** oo)
      (oo[1] == oo[2]) & (tr[1] == tr[2])
    }
    
    ## more test cases
    x1 <- c(0.019, 0.011)
    x2 <- c(0.01, 0.001)
    
    f(x)  ## TRUE
    f(x1) ## TRUE
    f(x2) ## FALSE
    

    Here is a more general function than the above for checking the last n instead of 2

    g <- function(x, n = 2) {
      oom <- function(x, base = 10) as.integer(ifelse(x == 0, 0, floor(log(abs(x), base))))
      x <- tail(x, n)
      oo <- oom(x)
      tr <- trunc(x / 10 ** oo)
      Reduce(`==`, oo) & Reduce(`==`, tr)
    }
    
    g(c(.24, .15, .14), 2)  ## TRUE
    g(c(.24, .15, .14), 3)  ## FALSE