Skip to contents

Reorder the elements of the data1 vector by flipping 2 randomly selected consecutive positions either:

- n times (when n is precised) or.

- until the correlation between data1 and data2 decreases down to the cor.limit (0.2 by default). See cor.limit below to deal with negative correlations.

Example of consecutive position flipping: ABCD -> BACD -> BADC, etc.

Designed for discrete values, but works also for continuous values.

Usage

permut(
  data1,
  data2 = NULL,
  n = NULL,
  seed = NULL,
  print.count = 10,
  text.print = "",
  cor.method = "spearman",
  cor.limit = 0.2,
  warn.print = FALSE,
  lib.path = NULL,
  safer_check = TRUE
)

Arguments

data1

A vector of at least 2 elements. Must be numeric if data2 is specified.

data2

A numeric vector of same length as data1.

n

Single numeric value of times "flipping 2 randomly selected consecutive positions". Ignored if data2 is specified.

seed

Single integer number used by set.seed(). Write NULL if random result is required, an integer otherwise. BEWARE: if not NULL, permut() will systematically return the same result when the other parameters keep the same settings.

print.count

Single integer value. Print a working progress message every print.count during loops. BEWARE: can increase substentially the time to complete the process using a small value, like 10 for instance. Use Inf is no loop message desired.

text.print

Single character string indicating the optional message to add to the working progress message every print.count loop.

cor.method

Correlation method. Either "pearson", "kendall" or "spearman". Ignored if data2 is not specified.

cor.limit

Single positive numeric proportion fixing the correlation limit. Ignored if data2 is not specified. Compute the correlation between data1 and data2, permute the data1 values, and stop the permutation process when the correlation between data1 and data2 decreases down below the cor limit value (0.2 by default). If cor(data1, data2) is negative, then -cor.limit is used and the process stops until the correlation between data1 and data2 increases up over cor.limit (-0.2 by default). BEWARE: write a positive cor.limit even if cor(data1, data2) is known to be negative. The function will automatically uses -cor.limit. If the initial correlation is already below cor.limit (positive correlation) or over -cor.limit (negative correlation), then the data1 value positions are completely randomized (correlation between data1 and data2 is expected to be 0).

warn.print

Single logical value. Print warnings at the end of the execution? No print if no warning messages

lib.path

Character vector specifying the absolute pathways of the directories containing the required packages if not in the default directories. Ignored if NULL.

safer_check

Single logical value. Perform some "safer" checks (see https://github.com/safer-r)? If TRUE, checkings are performed before main code running: 1) R classical operators (like "<-") not overwritten by another package because of the R scope and 2) required functions and related packages effectively present in local R lybraries. Set to FALSE if this fonction is used inside another "safer" function to avoid pointless multiple checkings.

Value

A list containing:

- $data: the modified vector.

- $warn: potential warning messages (in case of negative correlation when data2 is specified). NULL if non warning message.

- $cor: a spearman correlation between the initial positions (1:length(data1) and the final positions if data2 is not specified and the final correlation between data1 and data2 otherwise, according to cor.method.

- $count: the number of loops used.

Details

WARNINGS

see # https://www.r-bloggers.com/strategies-to-speedup-r-code/ for code speedup

The random switch of non consecutive positions (ABCD -> DBCA for instance) does not work very well as the correlation is quickly obtained but the initial vector structure is mainly kept (no much order).

Ths code would be: pos <- ini.pos[1:2] ; pos <- sample.int(n = n , size = 2, replace = FALSE) ; tempo.pos[pos] <- tempo.pos[rev(pos)]

Author

Gael Millot <gael.millot@pasteur.fr>

Yushi Han <yushi.han2000@gmail.com>

Haiding Wang <wanghaiding442@gmail.com>

Examples

permut(data1 = 1:10, data2 = 10:1, seed = 1, print.count = 1e4, text.print = "", cor.method = "spearman", cor.limit = 0.7)
#> 
#> CORRELATION DECREASE AFTER A SINGLE PERMUTATION: 0.01212
#> FIRST WHILE LOOP STEP -> GOING OUT FROM EQUALITY | LOOP COUNT: 1 | CORRELATION LIMIT: 0.7 | ABS TEMPO CORRELATION: 0.9879
#> FIRST WHILE LOOP STEP END | LOOP COUNT: 1 | CORRELATION LIMIT: 0.7 | ABS TEMPO CORRELATION: 0.9879 | TOTAL SPENT TIME: 0.0061
#> WHILE/FOR LOOPS INITIATION | LOOP COUNT: 1 | CORRELATION LIMIT: 0.7 | ABS TEMPO CORRELATION: 0.9879
#> INITIAL SETTINGS BEFORE ROUND: 1 | LOOP COUNT: 1 | GO BACK: FALSE | LOOP NUMBER ESTIMATION: 29,687.5 | CORRELATION LIMIT: 0.7 | ABS TEMPO CORRELATION: 0.9879
#> FOR LOOP | ROUND 1 | LOOP: 10,000 / 29,687.5 | TIME SPENT: 0.012 | EXPECTED END: 2024-09-03 17:28:29.075923
#> FOR LOOP | ROUND 1 | LOOP: 20,000 / 29,687.5 | TIME SPENT: 0.028 | EXPECTED END: 2024-09-03 17:28:29.080755
#> INITIAL SETTINGS BEFORE ROUND: 2 | LOOP COUNT: 1 | GO BACK: TRUE | LOOP NUMBER ESTIMATION: 14,843.75 | CORRELATION LIMIT: 0.7 | ABS TEMPO CORRELATION: 0.9879
#> FOR LOOP | ROUND 2 | LOOP: 10,000 / 14,843.75 | TIME SPENT: 0.013 | EXPECTED END: 2024-09-03 17:28:29.105795
#> FINAL WHILE LOOP | LOOP COUNT: 1 | CORRELATION LIMIT: 0.7 | ABS TEMPO CORRELATION: 0.9879
#> WHILE/FOR LOOPS END | LOOP COUNT: 16 | NB OF ROUNDS: 3 | CORRELATION LIMIT: 0.7 | ABS TEMPO CORRELATION: 0.697 | TOTAL SPENT TIME: 0.69
#> 
#> $data
#>  [1]  2  1  3  5  7 10  8  4  6  9
#> 
#> $warn
#> [1] "(1) INITIAL SPEARMAN CORRELATION BETWEEN data1 AND data2 HAS BEEN DETECTED AS NEGATIVE: -1. THE LOOP STEPS WILL BE PERFORMED USING POSITIVE CORRELATIONS BUT THE FINAL CORRELATION WILL BE NEGATIVE"
#> 
#> $cor
#> [1] -0.6969697
#> 
#> $count
#> [1] 16
#> 

permut(data1 = c(0,0,0,0,0), n = 5, data2 = NULL, seed = 1, print.count = 1e4, cor.limit = 0.5)
#> 
#> 
#> $data
#> [1] 0 0 0 0 0
#> 
#> $warn
#> [1] "(1) NO PERMUTATION PERFORMED BECAUSE data1 ARGUMENT SEEMS TO BE MADE OF IDENTICAL ELEMENTS: 0"
#> 
#> $cor
#> [1] 1
#> 
#> $count
#> [1] 0
#>