web-dev-qa-db-fra.com

Générer des chaînes aléatoires

Je souhaite générer des chaînes aléatoires de la manière suivante: ABCDE1234E, c’est-à-dire que chaque chaîne contient 5 caractères, 4 chiffres, puis 1 caractère.

J'ai trouvé un moyen de créer cela en utilisant le code suivant.

library(random)
string_5 <- as.vector(randomStrings(n=5000, len=5, digits=FALSE, upperalpha=TRUE,
                        loweralpha=FALSE, unique=TRUE, check=TRUE))
number_4 <- as.vector(randomNumbers(n=5000, min=1111, max=9999, col=5, base=10, check=TRUE))
string_1 <- as.vector(randomStrings(n=5000, len=1, digits=FALSE, upperalpha=TRUE,
                         loweralpha=FALSE, unique=FALSE, check=TRUE))
PAN.Number <- paste(string_5,number_4,string_1,sep = "")

Mais ces fonctions prennent beaucoup de temps et la bibliothèque random nécessite une connexion réseau.

> system.time(string_5 <- as.vector(randomStrings(n=5000, len=5, digits=FALSE, upperalpha=TRUE,
+                                                 loweralpha=FALSE, unique=TRUE, check=TRUE)))
   user  system elapsed 
   0.07    0.00    3.18 

Existe-t-il une méthode que je pourrais essayer pour réduire le temps d'exécution? J'ai aussi essayé d'utiliser sample() mais je ne pouvais pas comprendre.

16
Nikhil Kumar

Utiliser "stringi" comme suggéré par @akrun sera plus rapide, mais ce qui suit est également très rapide et ne nécessite aucun paquet supplémentaire:

myFun <- function(n = 5000) {
  a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
  paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}

Exemple de sortie:

myFun(10)
##  [1] "BZHOF3737P" "EPOWI0674X" "YYWEB2825M" "HQIXJ5187K" "IYIMB2578R"
##  [6] "YSGBG6609I" "OBLBL6409Q" "PUMAL5632D" "ABRAT4481L" "FNVEN7870Q"
22

Nous pouvons utiliser stri_Rand_strings de stringi

library(stringi)
sprintf("%s%s%s", stri_Rand_strings(5, 5, '[A-Z]'),
      stri_Rand_strings(5, 4, '[0-9]'), stri_Rand_strings(5, 1, '[A-Z]'))

Ou plus compactement

do.call(paste0, Map(stri_Rand_strings, n=5, length=c(5, 4, 1),
            pattern = c('[A-Z]', '[0-9]', '[A-Z]')))

Des repères

system.time({
    do.call(paste0, Map(stri_Rand_strings, n=5000, length=c(5, 4, 1),
            pattern = c('[A-Z]', '[0-9]', '[A-Z]')))
    })
#  user  system elapsed 
#   0      0      0

A été capable de reproduire les timings même pour une partie de la sortie attendue en utilisant la méthode de OP

system.time(string_5 <- as.vector(randomStrings(n=5000, len=5, digits=FALSE, upperalpha=TRUE,
                                              loweralpha=FALSE, unique=TRUE, check=TRUE)))
#  user  system elapsed 
#   0.86    0.24    5.52 
18
akrun

Vous pouvez effectuer directement ce que vous voulez: Échantillon de 5 lettres majuscules au hasard Échantillon de 4 chiffres Échantillon d'une lettre majuscule aléatoire

digits = 0:9
createRandString<- function() {
  v = c(sample(LETTERS, 5, replace = TRUE),
        sample(digits, 4, replace = TRUE),
        sample(LETTERS, 1, replace = TRUE))
  return(paste0(v,collapse = ""))
}

Cela sera plus facilement contrôlé et ne prendra pas aussi longtemps.

5
Shahar Bental

Au cas où quelqu'un viendrait ici chercher un moyen de générer des noms de fichiers aléatoires, voici ce que j'ai utilisé. Je l'aime pour son élégance

library(dplyr)
runif(1, 1000000000000, 9999999999999) %>% round %>% as.character %>% paste0("/tmp/", ., ".png") 

Remarque: vous pouvez facilement modifier le nombre de chaînes aléatoires générées en remplaçant le 1 dans runif() par le nombre souhaité.

0
user5783745