在 R 中调用组合函数循环 foreach 时出错
error calling combine function loop foreach in R
以下代码:
df <- foreach(i = 1:length, .combine = cbind) %dopar% {
...
...
m4
}
给我一个错误:
error calling combine function:
<simpleError in data.frame(..., check.names = FALSE): arguments imply differing number of rows: 17, 0>
但是,如果我使用 "for" 而不是 "foreach" 执行相同的代码,并且我还手动进行 cbind:
for (i in 1:lengthGeni) {
...
...
mFinaleCGunificati <- cbind(mFinaleCGunificati, m4)
}
一切正常
从 ?cbind
我们得知
If there are several matrix arguments, they must all have the same number of columns (or rows) and this will be the number of columns (or rows) of the result. If all the arguments are vectors, the number of columns (rows) in the result is equal to the length of the longest vector.
但是如果从这两个cbind例子的比较来看
# second df with one row
cbind(as.data.frame(matrix(rep(1, 10), nrow = 5)),
as.data.frame(matrix(rep(2, 2), nrow = 1)))
# V1 V2 V1 V2
# 1 1 1 2 2
# 2 1 1 2 2
# 3 1 1 2 2
# 4 1 1 2 2
# 5 1 1 2 2
# second df with zero rows
cbind(as.data.frame(matrix(rep(1, 10), nrow = 5)),
as.data.frame(matrix(rep(2, 0), nrow = 0)))
# Error in data.frame(..., check.names = FALSE) :
# arguments imply differing number of rows: 5, 0
我们了解到零长度对象是不允许的。
因此,您应该检查循环中的结果是否有任何大于 0 的行数。
library(foreach)
library(doSNOW)
cl <- makeSOCKcluster(5)
registerDoSNOW(cl)
df <- foreach(i = 1:2, .combine = cbind) %dopar% {
if (i == 1){
x <- as.data.frame(matrix(rep(1, 5), nrow = 5))
} else {
x <- as.data.frame(matrix(rep(1, 2), nrow = 1))
}
# check if result has at least one row
if (nrow(x) > 0){
x
}
}
df
# V1 V1 V2
# 1 1 2 2
# 2 1 2 2
# 3 1 2 2
# 4 1 2 2
# 5 1 2 2
但是请记住,较短的向量将被重复使用。因此,这种方法可能会导致代码中出现冗余。
为了避免冗余,您可以考虑在 foreach
循环中返回之前匹配结果的长度。
以下代码:
df <- foreach(i = 1:length, .combine = cbind) %dopar% {
...
...
m4
}
给我一个错误:
error calling combine function:
<simpleError in data.frame(..., check.names = FALSE): arguments imply differing number of rows: 17, 0>
但是,如果我使用 "for" 而不是 "foreach" 执行相同的代码,并且我还手动进行 cbind:
for (i in 1:lengthGeni) {
...
...
mFinaleCGunificati <- cbind(mFinaleCGunificati, m4)
}
一切正常
从 ?cbind
我们得知
If there are several matrix arguments, they must all have the same number of columns (or rows) and this will be the number of columns (or rows) of the result. If all the arguments are vectors, the number of columns (rows) in the result is equal to the length of the longest vector.
但是如果从这两个cbind例子的比较来看
# second df with one row
cbind(as.data.frame(matrix(rep(1, 10), nrow = 5)),
as.data.frame(matrix(rep(2, 2), nrow = 1)))
# V1 V2 V1 V2
# 1 1 1 2 2
# 2 1 1 2 2
# 3 1 1 2 2
# 4 1 1 2 2
# 5 1 1 2 2
# second df with zero rows
cbind(as.data.frame(matrix(rep(1, 10), nrow = 5)),
as.data.frame(matrix(rep(2, 0), nrow = 0)))
# Error in data.frame(..., check.names = FALSE) :
# arguments imply differing number of rows: 5, 0
我们了解到零长度对象是不允许的。
因此,您应该检查循环中的结果是否有任何大于 0 的行数。
library(foreach)
library(doSNOW)
cl <- makeSOCKcluster(5)
registerDoSNOW(cl)
df <- foreach(i = 1:2, .combine = cbind) %dopar% {
if (i == 1){
x <- as.data.frame(matrix(rep(1, 5), nrow = 5))
} else {
x <- as.data.frame(matrix(rep(1, 2), nrow = 1))
}
# check if result has at least one row
if (nrow(x) > 0){
x
}
}
df
# V1 V1 V2
# 1 1 2 2
# 2 1 2 2
# 3 1 2 2
# 4 1 2 2
# 5 1 2 2
但是请记住,较短的向量将被重复使用。因此,这种方法可能会导致代码中出现冗余。
为了避免冗余,您可以考虑在 foreach
循环中返回之前匹配结果的长度。