set.seed 在 for 循环中

set.seed in for loop

我正在做一些分析,我不得不估算一些值。为此,我编写了这段代码:

A)

set.seed(1)
for (i in 2:length (Dataset[-c(8,11)])) { 
      Dataset[,i]<-impute(Dataset[,i], "random")
}

[[-c(8,11) 用于两个字符列]]

这不会给我任何错误,所以我不是在要求这个,但是:将 Set.seed(1) 放在 for 循环之外是否正确? 因为我第二次 运行 这段代码的结果(在分析结束时)是不同的。 所以我把 Set.seed(1) 放在 for 循环中,像这样:

B)

for (i in 2:length (Dataset[-c(8,11)])) { 
      set.seed(1)
      Dataset[,i]<-impute(Dataset[,i], "random")
}

这给了我一个可重现的结果,但是如果我再次把 set.seed 放在外面,现在结果就像在 B 中一样卡住(当它在 for 循环内时)。

所以我很困惑:为什么会这样?语法有什么问题? 我怎样才能有效地编写一个带有 set.seed 的 for 循环来估算数据集中的某些值?

首先,您的代码并没有按照您的想法行事。问题是

for (i in 2:length(Dataset[-c(8,11)]))

您没有从循环中删除列,只是从数据框的长度中删除。如果数据框有 20 列,您将 运行 从第 2 列循环到第 18 列,因为您刚刚减少了列数。相反,您应该使用 i in 2:length(Dataset)[-c(8, 11)]。如果是字符数据,impute 将跳过这些列,因此您无需将它们排除在循环之外。

其次,当种子出现在循环之外时,我们可以测试您关于结果再现性的问题。下面是一个使用R自带的iris数据集的小例子:

data(iris)
set.seed(42)
Data <- iris[1:25, -5]
idx <- matrix(replicate(4, sample.int(25, 5)), 20)
idx <- cbind(idx, rep(1:4, each=5))
Data[idx] <- NA
head(Data)
#   Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1           NA         3.5          1.4         0.2
# 2          4.9         3.0          1.4         0.2
# 3          4.7         3.2          1.3          NA
# 4           NA          NA          1.5          NA
# 5           NA         3.6           NA          NA
# 6          5.4         3.9          1.7         0.4

现在我们对缺失值进行三次插补:

library(Hmisc)
set.seed(1)
for (i in 1:4) {
    Data[, i] <- impute(Data[, i], "random")
}
Data[idx]
#  [1] 5.8 4.9 4.6 4.7 5.4 3.4 3.5 3.3 3.6 3.8 1.3 1.5 1.5 1.5 1.5 0.2 0.2 0.2 0.1 0.3
set.seed(1)
for (i in 1:4) {
    Data[, i] <- impute(Data[, i], "random")
}
Data[idx]
#  [1] 5.8 4.9 4.6 4.7 5.4 3.4 3.5 3.3 3.6 3.8 1.3 1.5 1.5 1.5 1.5 0.2 0.2 0.2 0.1 0.3
set.seed(1)
for (i in 1:4) {
    Data[, i] <- impute(Data[, i], "random")
}
Data[idx]
#  [1] 5.8 4.9 4.6 4.7 5.4 3.4 3.5 3.3 3.6 3.8 1.3 1.5 1.5 1.5 1.5 0.2 0.2 0.2 0.1 0.3

每次估算的值都相同。