Neonira
by Neonira

Categories

  • programming-language

Tags

  • R
  • computer

We all face moments where we feel as not being as smart as expected. You know, those times where we lack of spirit presence, and of connection with the real world. It sometimes happen with R too, and that’s the subject of today’s post. Let’s focus on some reccuring needs, and how to address them gracefully in a very concise and convenient way.

Shuffling a vector

Real need, recurring and generally solution has to be rediscovered at each time.

#R code 
shuffle <- function(x_v) x_v[order(runif(length(x_v)))]

This function allows to shuffle any vector, even empty ones, as c() is another way to say NULL.

#R test session  
> shuffle(c())
NULL
> shuffle(1:15)
[1]  6  3  4  8 13 15  5 10  2 11  1 14  7  9 12

Nota Bene: shuffling does not imply that each item will change. Know it! If you need an absolute shuffle, this function is not the right one.

Matrix display in reverse order

Let’s consider a n*m matrix. Of course, using print allows to print the matrix. But how to print it in reverse order of rows?

#R code 
revmat <- function(x_m) apply(x_m, 2, rev)

This will do the job

#R test session 
> ma <- matrix(1:63, nrow = 7, byrow = TRUE)
> ma
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    2    3    4    5    6    7    8    9
[2,]   10   11   12   13   14   15   16   17   18
[3,]   19   20   21   22   23   24   25   26   27
[4,]   28   29   30   31   32   33   34   35   36
[5,]   37   38   39   40   41   42   43   44   45
[6,]   46   47   48   49   50   51   52   53   54
[7,]   55   56   57   58   59   60   61   62   63
> revmat(ma)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,]   55   56   57   58   59   60   61   62   63
[2,]   46   47   48   49   50   51   52   53   54
[3,]   37   38   39   40   41   42   43   44   45
[4,]   28   29   30   31   32   33   34   35   36
[5,]   19   20   21   22   23   24   25   26   27
[6,]   10   11   12   13   14   15   16   17   18
[7,]    1    2    3    4    5    6    7    8    9

Determining if a number is a whole number

I call a whole number a pure integer. So, how do you determine in R if a number is a whole number?

#R trial session
> is.integer(1)
FALSE

> is.integer(1L)
TRUE

I would have expected each of these to answer true. R manual recommends to use following R function to determine if a number is a whole number

#R code from R manual page is.integer
is.wholenumber <- function(x, tol = .Machine$double.eps^0.5)  abs(x - round(x)) < tol

Again, not what I expect, as this does have some undesirable side effects. See below

#R test session 
> e <- exp(1)
> l <- list(-3L, 0L, 48L, -2, 1, pi, 1 + 1i, 1 - 1i, complex(r = pi, i = e), 
            TRUE, FALSE, 1L + TRUE, 1L + FALSE, 1.1 + TRUE, 1.1 + FALSE)
> dt <- data.table(text = as.character(l), whole = sapply(l, is.wholenumber))
> dt
                                  text whole
 1:                                 -3  TRUE
 2:                                  0  TRUE
 3:                                 48  TRUE
 4:                                 -2  TRUE
 5:                                  1  TRUE
 6:                   3.14159265358979 FALSE
 7:                               1+1i  TRUE
 8:                               1-1i  TRUE
 9: 3.14159265358979+2.71828182845905i FALSE
10:                               TRUE  TRUE
11:                              FALSE  TRUE
12:                                  2  TRUE
13:                                  1  TRUE
14:                                2.1 FALSE
15:                                1.1 FALSE
> 

So, complex numbers are whole numbers if their real and imaginary parts are whole numbers. Strange, and not what I expect. So what is the correct, implementation to know if a number is an integer number?

DON’T: use is.wholenumber to test for a whole number as it appears insufficiently restrictive to do so.

#R code
> isAnIntegerNumber <- function(x) is.numeric(x) & is.wholenumber(x)
> dk <- data.table(text = as.character(l), whole = sapply(l, isAnIntegerNumber))
> dk
                                  text whole
 1:                                 -3  TRUE
 2:                                  0  TRUE
 3:                                 48  TRUE
 4:                                 -2  TRUE
 5:                                  1  TRUE
 6:                   3.14159265358979 FALSE
 7:                               1+1i FALSE
 8:                               1-1i FALSE
 9: 3.14159265358979+2.71828182845905i FALSE
10:                               TRUE FALSE
11:                              FALSE FALSE
12:                                  2  TRUE
13:                                  1  TRUE
14:                                2.1 FALSE
15:                                1.1 FALSE
> 

Finally, we got the right answer. This one is really counter intuitive and not so easy to remind.
DO: use isAnIntegerNumber to test for a whole number as it appears insufficient restrictive to do so.
TIP: those functions are good candidates for your .Rprofile.