如何简化以下r代码。.因为要花很多时间
I1 <- 0
m <- 10
for (k1 in 0:m) {
for (k2 in 0:m) {
for (s1 in 0:m) {
for (s2 in 0:m) {
I1 <- I1 + C.n(c((k1)/m,(k2)/m),uc) *
C.n(c((s1)/m,(s2)/m),uc) *
choose(m,k1) * choose(m,k2) *
choose(m,s1) * choose(m,s2) *
beta((k1) + (s1) + 1, 2*m-(k1)-(s1) + 1) *
beta((k2) + (s2) + 1, 2*m-(k2)-(s2) + 1)
}
}
}
}
答案 0 :(得分:1)
在我的第一条评论中,您可能会满意:
I1 <- 0
m <- 10
for (k1 in 0:m) {
ch_mk1 <- choose(m,k1)
for (k2 in 0:m) {
ch_mk2 <- choose(m,k2)
ch_mk <- ch_mk1 * ch_mk2
for (s1 in 0:m) {
ch_ms1 <- choose(m,s1)
be_k1s1 <- beta((k1) + (s1) + 1, 2*m-(k1)-(s1) + 1)
for (s2 in 0:m) {
ch_ms2 <- choose(m,s2)
be_k2s2 <- beta((k2) + (s2) + 1, 2*m-(k2)-(s2) + 1)
I1 <- I1 + C.n(c((k1)/m,(k2)/m),uc) *
C.n(c((s1)/m, (s2)/m), uc) *
ch_mk * ch_ms1 * ch_ms2 *
be_k1s1 * be_k2s2
}
}
}
}
(我应该注意,这里和所有代码都未经测试,因为我没有您的功能。)
尽管这仍然有点低效。实话实说,我认为您根本不需要for
循环。 R的许多功能真的很喜欢一次在整个矢量上执行操作,其中choose
和beta
就在其中。
尝试一下,完全删除for
循环:
eg <- expand.grid(k1 = 0:m, k2 = 0:m, s1 = 0:m, s2 = 0:m)
ch_mk1 <- choose(m, eg$k1)
ch_mk2 <- choose(m, eg$k2)
ch_ms1 <- choose(m, eg$s1)
ch_ms2 <- choose(m, eg$s2)
be_k1s1 <- beta((eg$k1) + (eg$s1) + 1, 2*m-(eg$k1)-(eg$s1) + 1)
be_k2s2 <- beta((eg$k2) + (eg$s2) + 1, 2*m-(eg$k2)-(eg$s2) + 1)
现在最大的问题是C.n
(和类似的uc
)。
如果它可以将参数作为矢量处理,请尝试以下操作:
I1 <- sum(
C.n(c((eg$k1)/m, (eg$k2)/m), uc) *
C.n(c((eg$s1)/m, (eg$s2)/m), uc) *
ch_mk1 * ch_mk2 * ch_ms1 * ch_ms2 *
be_k1s1 * be_k2s2
)
如果不能将其参数作为矢量处理(或者即使可以,但无论如何您都想使用它),则尝试以下操作:
I1 <- sum(
mapply(C.n, (eg$k1)/m, (eg$k2)/m, uc) *
mapply(C.n, (eg$s1)/m, (eg$s2)/m, uc) *
ch_mk1 * ch_mk2 * ch_ms1 * ch_ms2 *
be_k1s1 * be_k2s2
)
因为这只是使用mapply
,所以如果您决定采用多处理路线(例如,parallel
包),它将很容易并行化,如@BenBolker在其评论中建议的那样。
意识到eg
将成倍增长,因此使用0:10
意味着11^4
或14,641行。如果m
实际上大了许多,则可能会遇到内存或向量长度限制。在这种情况下,您可以使用保留了外部两个循环(k1
和k2
)并在内部两个循环(例如expand.grid
上使用expand.grid(s1 = 0:m, s2 = 0:m)
的混合解决方案)在那里进行矢量化。或相反(展开k1
和k2
,循环s1
和s2
)。