我目前正在使用apTreeshape使用“Yule-Hardy”方法模拟系统发育树。我想要做的是为三个不同的分组(小型,中型和大型树)随机生成20到25个不同的数字,然后为从分组中选择的每个随机数生成大约40棵树。
我知道如何在Python的Python中做到这一点,但在R中,事情看起来有点不同。
我的想法是,如果我要生成一个充满随机数的向量(每个大小分组一个),然后用它来生成一个基本上包含每个随机数的所有重复值的向量。
这就是我所拥有的:
sm_leaves<-c(sample(3:50,25,replace=F));
s_leafy<-numeric();
for (i in 1:length(sm_leaves)) {
for (j in 1:10) {
s_leafy[j+i-1]=sm_leaves[i];
}
}
这给我的输出如下:
> s_leafy
[1] 5 38 6 22 29 20 19 46 9 18 39 50 34 11 43 7 8 32 10 42 14 37
[23] 23 13 28 28 28 28 28 28 28 28 28 28
但我想要的更像是:
> s_leafy
[1] 5 5 5 5 5 5 5 5 5 5 38 38 38 38 38 38 38 38 38 ... 28 28 28 28 28 28 28 28 28 28
我这样做的原因仅仅是我可以将这个向量与所有随机生成的树一起附加到数据框架 - 我需要2000个,所以手动执行此操作并不太实际。
我真的能够从我之前尝试解决这个问题的推论中得出的结论是,一般来说应该使用循环而不是for循环,很多人都谈到使用expand.grid,但我不认为后者在这种情况下特别有用。
感谢您的阅读,我希望我的问题不是太微不足道(虽然我不会感到惊讶)。
答案 0 :(得分:5)
使用'rep'显然是如何在R中快速完成此操作的答案,但为什么您的代码不起作用?一点调查揭示了原因。
首先,取出随机性并给自己一个简单,可重复的例子。将sm_leaves设置为c(3,4,5),看看会发生什么。你得到:
3 4 5 5 5 5 5 5 5 5 5 5
仍然看起来不对劲。你预计10个3s,10个4s,10个5s吧?嗯。在循环中添加一个print语句,以查看值被卡住的位置:
> for (i in 1:length(sm_leaves)) {
for (j in 1:10) {
print(j+i-1)
s_leafy[j+i-1]=sm_leaves[i];
}
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
...etc....
糟糕。你的矢量索引是错误的。 j + i-1在每个内循环后跳回并覆盖先前的值。你想要:
s_leafy[j + (i - 1)*10]=sm_leaves[i];
所以也许这只是一个简单的例子,你错过了表达式中的* 10!
但请注意,很多简单的矢量操作最好使用R的函数,如rep,seq和“[”,如此处的其他答案中所述。
答案 1 :(得分:4)
如果我不太了解这个问题,请道歉,但是:
sm_leaves <- sample(3:50, 25, replace=FALSE)
s_leafy <- rep(sm_leaves, each=10)
答案 2 :(得分:1)
您希望rep()
使用each=10
选项:
> set.seed(42)
> sm_leaves <- sample(3:50,25,replace=F)
> s_leafy <- rep(sm_leaves, each=3) ## here rep=3 to generate small sample
> s_leafy
[1] 46 46 46 47 47 47 16 16 16 40 40 40 31 31 31 25 25
[18] 25 33 33 33 8 8 8 29 29 29 30 30 30 20 20 20 42
[35] 42 42 36 36 36 11 11 11 18 18 18 34 34 34 35 35 35
[52] 6 6 6 17 17 17 19 19 19 28 28 28 44 44 44 41 41
[69] 41 26 26 26 4 4 4
>