如何在R中正确编写双for
循环?
例如,在C中我会做
int i, j;
for (i = 1; i < 6; i++) {
for (j=i; j <= 3; j++) {
printf("%i,%i\n",i,j);
}
// Do more operations for i > 3...
}
将生成(人工)序列:
1,1
1,2
1,3
2,2
2,3
3,3
在R中,当你写
时,你不会得到相同的行为for (i in 1:6) {
for (j in i:3) {
print(paste(i,j,sep=","))
}
}
所以我已经沦为做
之类的事了for (i in 1:6) {
j <- i
while (j <= 3) {
print(paste(i,j,sep=","))
j <- j+1
}
}
有更好的方法吗?
正如Shane所说,也许我应该说清楚:我对代码式的数学匹配特别感兴趣,以便学生更容易理解。学生似乎对for
循环感到最舒服。
特别是,我希望我的学生模拟LIBOR market model。在相同的概率测度下模拟前向速率的动态。因此,对于每个时间步和每个 前向速率,需要计算和添加适当的漂移校正\ mu_i。
答案 0 :(得分:12)
很抱歉询问什么是可能是一个愚蠢的问题,但在什么意义上R不能这样做?这对我来说非常好:
N <- 5
for (i in 0:(2*N)) {
for (j in i:N) {
print(paste(i,j,sep=","))
}
}
难道你只是没有在序列的末尾加上括号吗?
编辑:我明白了...你想强制执行i:3序列总是&lt; = 3?我认为无论是序列还是for语句的子句都不可能。你可以在循环中设置一个中断,但这并不比你当前的方法更好:
for (i in 1:6) {
for (j in i:3) {
if(j > 3) break()
print(paste(i,j,sep=","))
}
}
这是在没有for循环的情况下生成此序列的另一种方法:
x <- cbind(rep(c(1,2,3), 3),
rep(c(1,2,3), each=3))
或者使用expand.grid(根据Dirk的建议):
x <- expand.grid(x=1:3, y=1:3)
然后删除不需要的案例:
x[x[,1] >= x[,2],]
编辑2:这可能不适合您的需求,但我相信Quantlib有一个Libor市场模型实施。我不确定它是exposed in RQuantlib。
答案 1 :(得分:10)
你当然可以嵌套循环:
R> for (i in 1:3) for (j in 1:3) cat(i,j,i*j, "\n")
1 1 1
1 2 2
1 3 3
2 1 2
2 2 4
2 3 6
3 1 3
3 2 6
3 3 9
R>
一般认为不应该,因为矢量化调用可以更容易读写:
R> outer(1:3,1:3, "*")
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 2 4 6
[3,] 3 6 9
R>
但如果使用nexted循环更容易开发,那么就这样做。
对于“依赖于第一个索引的第二个索引”问题,您可以使用lower.tri(),upper.tri()或索引来实现这一目标。
R> X <- expand.grid(x=1:3, y=1:3)
R> X <- X[ X$x >= X$y, ]
R> outer(X$x, X$y, "*")
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 2 2 3
[2,] 2 2 2 4 4 6
[3,] 3 3 3 6 6 9
[4,] 2 2 2 4 4 6
[5,] 3 3 3 6 6 9
[6,] 3 3 3 6 6 9
R>
答案 2 :(得分:6)
这里的问题是i:3
在i>3
时有意义。例如,5:3
会(5,4,3)
。您只需要一个简单的if语句来阻止在i>3
时运行第二个循环。
for (i in 1:6) {
if(i < 4) {
for (j in i:3) {
print(paste(i,j,sep=","))
}
}
# Do more operations for i > 3...
}
但是,如果可能的话,尽量避免显式循环。 Dirk和Shane的答案为如何做到这一点提供了一些想法。