竟然被awk生成的随机数给整蒙了,也谈随机数生成种子
我們現在主要的一個業務是給科研單位等提供數據庫構建服務,目前承接的數據庫已經發表了3篇NAR文章,具體見你的數據也可以-三篇NAR的數據庫。
這次一位老師需要做數據庫,但數據還沒做好,時間要求卻比較急,我們只能隨機生成一些數據來作為測試先把數據庫搭起來,等完成后再替換為真實數據,稍加測試,也就完成了。
最開始是這么生成隨機數字的,看上去沒問題,每運行一次都會生成一個隨機數,符合預期。
awk 'BEGIN{OFS=FS="\t";}{ $2=100 * rand(); print $0;}' 00232503-7e34-479a-b6fb-0b52e78b554e.txt | cut -f 1-3 | head Rnu7-186P 99.4034 ACC-3 Rnu2-41P 24.6362 ACC-3awk 'BEGIN{OFS=FS="\t";}{ $2=100 * rand(); print $0;}' 00232503-7e34-479a-b6fb-0b52e78b554e.txt | cut -f 1-3 | head Rnu7-186P 24.3382 ACC-3 Rnu2-41P 87.6752 ACC-3但當放到一個for循環中時 ,問題就出來了,每次循環的隨機數都一樣:
for i in *.txt; do awk 'BEGIN{OFS=FS="\t";}{ $2=100 * rand(); print $0;}' $i | cut -f 1-3 | head -n 2; echo "------------"; done Rnu7-186P 99.0514 ACC-3 Rnu2-41P 82.4637 ACC-3 ------------ Rnu7-186P 99.0514 ACC-3 Rnu2-41P 82.4637 ACC-3 ------------ Rnu7-186P 99.0514 ACC-3 Rnu2-41P 82.4637 ACC-3 ------------這猜測是每次循環時隨機數發生器給的種子都是一致的,導致隨機數在每個循環都一致了,修改如下:每次循環單獨給一個隨機數的種子就好了。
for i in `seq 1 3`; do awk -v seed=$RANDOM 'BEGIN{OFS=FS="\t";srand(seed);}{ $2=100 * rand(); print $0;}' 00232503-7e34-479a-b6fb-0b52e78b554e.txt | cut -f 1-3 | head -n 2; echo "------------"; done Rnu7-186P 38.0502 ACC-3 Rnu2-41P 76.7106 ACC-3 ------------ Rnu7-186P 99.1498 ACC-3 Rnu2-41P 65.7196 ACC-3 ------------ Rnu7-186P 92.9258 ACC-3 Rnu2-41P 24.0214 ACC-3 ------------這就是awk自己的坑了。
In most awk implementations, including gawk, rand() starts generating numbers from the same starting number, or seed, each time you run awk. Thus, a program generates the same results each time you run it. The numbers are random within one awk run but predictable from run to run. This is convenient for debugging, but if you want a program to do different things each time it is used, you must change the seed to a value that is different in each run. To do this, use srand().
隨機數生成器的種子
除了在顯示生成隨機數做測試時會用到隨機數生成器,很多其它時候比如做Kmeans聚類時,WGCNA分析時, 隨機森林分析時也都會有隨機過程,每次運行結果都有可能不同,為了保證結果的可重復性,這時就可以設置一個隨機數種子。其原則是:種子定了,每次運行結果也就不會變了。
通常這個種子是一個整數,任意整數都可以。講課時,我一般說大家可以選擇自己的幸運數字來設置,在R中通常通過函數set.seed來設置:
通常,如果我們沒有自己設置種子,大部分程序語言中會調用當前的時間戳作為隨機數的種子,每次操作時間都不同,時間戳也就不同,獲得的隨機數序列也就不同。
下面是一個R中的示例,可以看到前面兩次運行rnorm(5)獲得的返回值都不同。而在設置set.seed(10)后,兩次運行rnorm(5)獲得的返回值完全一致。當然這個設置只是對最近的命令有效,下面再運行一次rnorm(5),又是基于時間戳生成的完全不同的數據。
# 不設置 rnorm(5) # [1] 1.1017795 0.7557815 -0.2382336 0.9874447 0.7413901 rnorm(5) # [1] 0.08934727 -0.95494386 -0.19515038 0.92552126 0.48297852set.seed(10) rnorm(5) # [1] 0.01874617 -0.18425254 -1.37133055 -0.59916772 0.29454513set.seed(10) rnorm(5) # [1] 0.01874617 -0.18425254 -1.37133055 -0.59916772 0.29454513rnorm(5) [1] 0.3897943 -1.2080762 -0.3636760 -1.6266727 -0.2564784關于隨機數種子,雖然看上去比較簡單,但每次課程,總會有多位老師問起,問起最多的就是為什么你選擇10作為隨機數種子?依據是什么?我怎么選?實際就記住兩點:
同一個隨機數種子獲得的隨機數序列是一致的,不管這個種子是10, 20還是 30。
隨機數種子可以是任意值,看心情選擇就好,課程中選哪個也都是隨機的。
這個為生信學習和生信作圖打造的開源R教程真香!!!
這個為生信學習打造的開源Linux教程真香!!!
往期精品(點擊圖片直達文字對應教程)
后臺回復“生信寶典福利第一波”或點擊閱讀原文獲取教程合集
?
(請備注姓名-學校/企業-職務等)
總結
以上是生活随笔為你收集整理的竟然被awk生成的随机数给整蒙了,也谈随机数生成种子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在一个热图中使用多个颜色主题
- 下一篇: 在家吃饭保平安,华人学者研究发现,经常在