Skip to contents
library(tinycodet)
#> Run `?tinycodet::tinycodet` to open the introduction help page of 'tinycodet'.

 

source_selection

The source_selection() function is the same as base R’s source() function, except that it allows only placing the selected objects and functions into the current environment, instead of all objects.

The objects to be selected can be specified using any combination of the following:

  • by supplying a character vector of exact object names to the select argument.
  • by supplying a character vector of regex patterns to the regex argument.
  • by supplying a character vector of fixed patterns to the fixed argument.

The regex and fixed arguments are especially handy when sourcing S3 methods. For example, to expose the following methods to the current environment, mymethod.numeric() and mymethod.character() from generic mymethod(), one could specify regex = "^mymethod".

Example:

exprs <- expression({
  helloworld = function()print("helloworld")
  goodbyeworld <- function() print("goodbye world")
  `%s+test%` <- function(x,y) stringi::`%s+%`(x,y)
  `%s*test%` <- function(x,y) stringi::`%s*%`(x,y)
  mymethod <- function(x) UseMethod("mymethod", x)
  mymethod.numeric <- function(x)x * 2
  mymethod.character <- function(x)chartr(x, old = "a-zA-Z", new = "A-Za-z")
})

temp.fun <- function(){
  source_selection(list(exprs=exprs), regex= "^mymethod", fixed = c("%", ":="))
  ls() # list all objects residing within the function definition
}
temp.fun()
#> Sourcing script ...
#> Done
#> [1] "%s*test%"           "%s+test%"           "mymethod"          
#> [4] "mymethod.character" "mymethod.numeric"

temp.fun <- function(){
  source_selection(list(exprs=exprs), select = c("helloworld", "goodbyeworld"))
  ls() # list all objects residing within the function definition
}
temp.fun()
#> Sourcing script ... 
#> 
#> Done
#> [1] "goodbyeworld" "helloworld"

 

Matrix re-ordering operators

The tinycodet R package adds 2 additional matrix operators:

  • The x %row~% mat operator re-orders the elements of every row, each row ordered independently from the other rows, of matrix x, by the ordering ranks given in matrix mat.
  • The x %col~% mat operator re-orders the elements of every column, each column ordered independently from the other columns, of matrix x, by the ordering ranks given in matrix mat.

If matrix x is a numeric matrix, and one wants to numerically sort the elements of every row or column, x %row~% x or x %col~% x would suffice, respectively.

If matrix x is not numeric, sorting using x %row~% x and x %col~% x is still possible, but probably not the best option. In the non-numeric case, providing a matrix of ordering ranks would probably be faster and give more accurate ordering.

If mat is a matrix of non-repeating random integers (i.e. sample(1:length(x), replace=FALSE)), x %row~% mat will randomly shuffle the elements of every row, where the shuffling order in each row is independent from the shuffling order in the other rows. Similarly, x %col~% mat will randomly shuffle the elements of every column, where the shuffling order in each column is independent from the shuffling order in the other columns.

Re-ordering/sorting every row/column of a matrix with these operators is generally faster than doing so through loops.

 

Examples with a numeric matrix:

x <- matrix(sample(1:25), nrow=5)
print(x)
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]   13   15   22   14   25
#> [2,]   23   20   19   10   11
#> [3,]   12    4    8   18   17
#> [4,]    5   21    2   16    1
#> [5,]    6    9    7   24    3
x %row~% x # sort elements of every row
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]   13   14   15   22   25
#> [2,]   10   11   19   20   23
#> [3,]    4    8   12   17   18
#> [4,]    1    2    5   16   21
#> [5,]    3    6    7    9   24
x %row~% -x # reverse-sort elements of every row
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]   25   22   15   14   13
#> [2,]   23   20   19   11   10
#> [3,]   18   17   12    8    4
#> [4,]   21   16    5    2    1
#> [5,]   24    9    7    6    3
x %col~% x # sort elements of every column
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    5    4    2   10    1
#> [2,]    6    9    7   14    3
#> [3,]   12   15    8   16   11
#> [4,]   13   20   19   18   17
#> [5,]   23   21   22   24   25
x %col~% -x # reverse-sort elements of every column
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]   23   21   22   24   25
#> [2,]   13   20   19   18   17
#> [3,]   12   15    8   16   11
#> [4,]    6    9    7   14    3
#> [5,]    5    4    2   10    1

x <- matrix(sample(1:25), nrow=5)
print(x)
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]   22    9    8    3    5
#> [2,]   11   10   25   13   16
#> [3,]    7    2    1   20   15
#> [4,]   21   17   14   23   12
#> [5,]    6    4   18   24   19
rand <- sample(1:length(x)) |> matrix(ncol=ncol(x)) # matrix of random integers
x %row~% rand # random shuffle every row independent of other rows
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    8    3    9    5   22
#> [2,]   25   11   13   10   16
#> [3,]    2   20    7    1   15
#> [4,]   21   17   12   14   23
#> [5,]    6   19   24    4   18
x %col~% rand # random shuffle every column independent of other columns
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    6   17    8   20   12
#> [2,]   21    2   25    3   19
#> [3,]    7    9   14   23    5
#> [4,]   11    4    1   24   16
#> [5,]   22   10   18   13   15

Examples with a character matrix:

x <- matrix(sample(letters, 25), nrow=5)
print(x)
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,] "b"  "n"  "t"  "r"  "k" 
#> [2,] "f"  "e"  "a"  "z"  "d" 
#> [3,] "g"  "x"  "m"  "p"  "h" 
#> [4,] "l"  "w"  "y"  "s"  "i" 
#> [5,] "v"  "q"  "o"  "c"  "j"
mat <- stringi::stri_rank(as.vector(x)) |>
  matrix(ncol=ncol(x)) # matrix of ordering ranks
x %row~% mat # sort elements of every row
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,] "b"  "k"  "n"  "r"  "t" 
#> [2,] "a"  "d"  "e"  "f"  "z" 
#> [3,] "g"  "h"  "m"  "p"  "x" 
#> [4,] "i"  "l"  "s"  "w"  "y" 
#> [5,] "c"  "j"  "o"  "q"  "v"
x %row~% -mat # reverse-sort elements of every row
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,] "t"  "r"  "n"  "k"  "b" 
#> [2,] "z"  "f"  "e"  "d"  "a" 
#> [3,] "x"  "p"  "m"  "h"  "g" 
#> [4,] "y"  "w"  "s"  "l"  "i" 
#> [5,] "v"  "q"  "o"  "j"  "c"
x %col~% mat # sort elements of every column
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,] "b"  "e"  "a"  "c"  "d" 
#> [2,] "f"  "n"  "m"  "p"  "h" 
#> [3,] "g"  "q"  "o"  "r"  "i" 
#> [4,] "l"  "w"  "t"  "s"  "j" 
#> [5,] "v"  "x"  "y"  "z"  "k"
x %col~% -mat # reverse-sort elements of every column
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,] "v"  "x"  "y"  "z"  "k" 
#> [2,] "l"  "w"  "t"  "s"  "j" 
#> [3,] "g"  "q"  "o"  "r"  "i" 
#> [4,] "f"  "n"  "m"  "p"  "h" 
#> [5,] "b"  "e"  "a"  "c"  "d"

x <- matrix(sample(letters, 25), nrow=5)
print(x)
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,] "b"  "f"  "z"  "p"  "l" 
#> [2,] "h"  "m"  "g"  "v"  "o" 
#> [3,] "i"  "t"  "d"  "q"  "y" 
#> [4,] "s"  "c"  "k"  "u"  "a" 
#> [5,] "x"  "w"  "n"  "r"  "j"
rand <- sample(1:length(x)) |> matrix(ncol=ncol(x)) # matrix of random integers
x %row~% rand # random shuffle every row independent of other rows
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,] "f"  "z"  "l"  "p"  "b" 
#> [2,] "m"  "v"  "g"  "h"  "o" 
#> [3,] "y"  "t"  "q"  "i"  "d" 
#> [4,] "a"  "s"  "k"  "c"  "u" 
#> [5,] "n"  "w"  "r"  "x"  "j"
x %col~% rand # random shuffle every column independent of other columns
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,] "s"  "m"  "z"  "v"  "y" 
#> [2,] "b"  "t"  "g"  "p"  "a" 
#> [3,] "h"  "f"  "n"  "q"  "l" 
#> [4,] "i"  "w"  "k"  "r"  "o" 
#> [5,] "x"  "c"  "d"  "u"  "j"

Because each row/column is re-ordered independently of all other columns, it would be deceptive to keep the row- and column-names, as they no longer hold. Thus, for consistency, these operators strip all attributes from the input matrix x.

 

Additional logic operators

The tinycodet package adds a few basic logic operators:

  • %xor%: Exclusive OR
  • %n&%: NOT AND (i.e. (!x) & (!y)). Note that if either x or y is NA, %n&% will also give NA (unlike (!x) & (!y), which would give FALSE.)
  • %?=%: checks if both x and y are unknown or unreal (NA, NaN, Inf, -Inf)
  • %out%: the opposite of %in% (i.e. !x %in% y)

Here are some examples:

x <- c(TRUE, FALSE, TRUE, FALSE, NA, NaN, Inf, -Inf, TRUE, FALSE)
y <- c(FALSE, TRUE, TRUE, FALSE, rep(NA, 6))
outcome <- data.frame(
  x=x, y=y,
  "x %xor% y"=x %xor% y, "x %n&% y" = x %n&% y, "x %?=% y" = x %?=% y,
  check.names = FALSE
)
knitr::kable(outcome)
x y x %xor% y x %n&% y x %?=% y
1 FALSE TRUE FALSE FALSE
0 TRUE TRUE FALSE FALSE
1 TRUE FALSE FALSE FALSE
0 FALSE FALSE TRUE FALSE
NA NA NA NA TRUE
NaN NA NA NA TRUE
Inf NA NA NA TRUE
-Inf NA NA NA TRUE
1 NA NA NA FALSE
0 NA NA NA FALSE

1:3 %out% 1:10
#> [1] FALSE FALSE FALSE
1:10 %out% 1:3
#>  [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

Numbers can have many different sub-types whilst still being numeric. The n %=numtype% numtype operator will check for every value of numeric vector n if it can be considered a number belonging to type numtype. The following values for numtype are allowed:

  • “~0”: zero, or else a number whose absolute value is smaller than the Machine tolerance (sqrt(.Machine$double.eps));
  • “B”: binary numbers (0 or 1);
  • “prop”: proportions;
  • “I”: Integers;
  • “odd”: odd integers;
  • “even”: even integers
  • “R”: Real numbers;
  • “unreal”: infinity, NA, or NaN;

The string counterpart for %=numtype% is s %=strtype% strtype, which checks for every value of character vector s if it can seen as a certain strtype. The following values for strtype are allowed:

  • “empty”: checks if the string only consists of empty spaces.
  • “unreal”: checks if the string is NA, or if it has literal string “NA”, “NaN” or “Inf”, regardless if it has leading or trailing spaces.
  • “numeric”: checks if the string can be converted to a number, disregarding leading and trailing spaces. I.e. the string “5.0” can be converted to the the actual number 5.0.
  • “special”: checks if the string consists of only special characters.

Here are some examples:


1e-20 %=numtype% "~0"
#> [1] TRUE
n <- c(0:5, 0:-5, 0.1, -0.1, 0, 1, Inf, -Inf, NA, NaN)
n[n %=numtype% "B"]
#> [1] 0 1 0 0 1
n[n %=numtype% "prop"]
#> [1] 0.0 1.0 0.0 0.1 0.0 1.0
n[n %=numtype% "B"]
#> [1] 0 1 0 0 1
n[n %=numtype% "I"]
#>  [1]  0  1  2  3  4  5  0 -1 -2 -3 -4 -5  0  1
n[n %=numtype% "odd"]
#> [1]  1  3  5 -1 -3 -5  1
n[n %=numtype% "even"]
#> [1]  0  2  4  0 -2 -4  0
n[n %=numtype% "R"]
#>  [1]  0.0  1.0  2.0  3.0  4.0  5.0  0.0 -1.0 -2.0 -3.0 -4.0 -5.0  0.1 -0.1  0.0
#> [16]  1.0
n[n %=numtype% "unreal"]
#> [1]  Inf -Inf   NA  NaN

s <- c(" AbcZ123 ", " abc ", " 1.3 ", " !#$%^&*() ", "  ", "  NA  ", "  NaN  ", " Inf ")
s[s %=strtype% "empty"]
#> [1] "  "
s[s %=strtype% "unreal"]
#> [1] "  NA  "  "  NaN  " " Inf "
s[s %=strtype% "numeric"]
#> [1] " 1.3 " " Inf "
s[s %=strtype% "special"]
#> [1] " !#$%^&*() "