问题与您初始化数据框的方式有关,以及在foreach
环境、选项stringsAsFactors
未设置为FALSE
。每个发生了什么foreach
循环是这样的
options(stringsAsFactors = FALSE)
d <- data.frame(x =character(0))
d[1, "x"] <- "a"
#Warning message:
#In `[<-.factor`(`*tmp*`, iseq, value = "a") :
# invalid factor level, NA generated
d
# x
#1 <NA>
请注意,这只会给出警告,而不是错误,因此循环不会停止。如果你设置stringsAsFactors
to FALSE
首先没有问题(就像你在不并行运行东西时所做的那样)
options(stringsAsFactors = FALSE)
d <- data.frame(x =character(0))
d[1, "x"] <- "a"
d
# x
#1 a
在你的全局环境中你已经设置了options(stringsAsFactors = FALSE)
so the %do%
循环有效。但是,此选项不会在每个并行作业的本地环境中传递,因此%dopar%
循环遇到了上面的问题。
例如,查看以下输出
options(stringsAsFactors = FALSE)
.Options$stringsAsFactors
#[1] FALSE
foreach(i = 1:3) %dopar% .Options$stringsAsFactors
#[[1]]
#[1] TRUE
#
#[[2]]
#[1] TRUE
#
#[[3]]
#[1] TRUE
所以解决方案是设置选项stringsAsFactors = FALSE
在 - 的里面foreach
loop.
顺便说一句,如果可能的话,使用整个列向量而不是逐行创建数据框要好得多。在你的例子中你可以替换
frame.results = data.frame(frame.name = character(0), mappedField = character(0), label = character(0))
for(col.i in 1:ncol(frame)) {
frame.results[col.i, "frame.name"] = frame.name
frame.results[col.i, "mappedField"] = colnames(frame)[col.i]
frame.results[col.i, "label"] = valslabel(frame[,col.i])
}
with
frame.results <- data.frame(
frame.name = frame.name,
mappedField = colnames(frame),
label = valslabel1(colMeans(frame)))
哪里的valslabel
函数已被矢量化版本取代
valslabel1 <- function(x) {
ifelse(x < 0.5, "low", "high")
}