web-dev-qa-db-ja.com

ランダム文字列の生成

次の方法でランダムな文字列を生成します:_ABCDE1234E_、つまり、各文字列には5文字、4数字、1文字が含まれます。

次のコードを使用してこれを作成する方法を見つけました。

_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 = "")
_

ただし、これらの関数には時間がかかり、randomライブラリにはネットワーク接続が必要です。

_> 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 
_

実行時間を短縮しようとする方法はありますか? sample()を使用してみましたが、理解できませんでした。

20
Nikhil Kumar

@akrunで提案されている「stringi」を使用すると高速になりますが、以下も非常に高速であり、追加のパッケージは不要です。

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))
}

出力例:

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

stringiからstri_Rand_stringsを使用できます

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]'))

またはよりコンパクトに

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

ベンチマーク

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

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 
19
akrun

あなたが望むものを直接実行することができます:ランダムな5つの大文字のサンプル4桁のサンプルランダムな1つの大文字のサンプル

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 = ""))
}

これはより簡単に制御され、それほど長くかかりません。

5
Shahar Bental

パフォーマンスの問題は、最初にrandomパッケージを使用することから生じます。インターネット検索でrandom::randomStrings()関数を見つけて、使用するランダムな文字列を生成するのに良い方法だと考えられることは理解できますプログラム内ではありますが、randomパッケージは汎用プログラミング用ではありませんRANDOM.ORG サーバーを照会することで機能します。これは、Rの組み込み擬似乱数ジェネレーターよりも本質的に低速です。

ランダムパッケージのビネット のいずれかから:

非決定論的に決定された乱数を使用することが望ましい多くの状況があります。例が含まれます
-真に独立したシードを使用して、異なるノードに分散コンピューティングをシードします。
-特定のオペレーティングシステムまたはハードウェア機能に依存しないRNGの移植可能な初期化を取得します。
-非決定論的な乱数を使用してシミュレーション結果を検証します。
-宝くじの抽選やゲームに使用される不確定なシードを提供する...

これらの例の大部分はseedingまたはinitializing(これらは同義語です)Rの組み込み擬似乱数ジェネレーターであることに注意してください。それらを置き換えるのではなく...

2
Ben Bolker

ランダムなファイル名を生成する方法を探している人がここに来た場合に備えて、ここで使用します。優雅さで気に入っています

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

注:runif()の_1_を必要な数に変更することで、生成するランダム文字列の数を簡単に変更できます

0
user5783745