You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言采样循环神秘Bug:赋值方式导致sample()结果不一致

R中sample()结果不一致的原因及修复

问题重现

在R代码中遇到sample()函数结果因调用次数而非赋值方式产生差异的问题,最小可复现代码如下:

# Sampling Bug MRE
rm(list = ls())
library(tidyverse)
ages=c(paste0("CHILD",seq(1,10),"AGE"))
set.seed(26)
df=c()
for(i in 1:10){
  x=round(runif(1:100,min=1,max=20),0)
  df = as.data.frame(cbind(df,x))
}
names(df)=ages

set.seed(26)
df$`Sampled Child`=0
test_vector=c()
for(i in 1:nrow(df)){
  childs_age = unlist(c(as.numeric(df[i,ages])))
  slice=which(childs_age<=17)
  if(length(slice)>=1){
    df$`Sampled Child`[i]=sample(x=slice,size=1,replace = F)
    test_vector=append(test_vector,sample(x=slice,size=1,replace = F))
  }
  else{
    df$`Sampled Child`[i]="Ineligibile"
    test_vector=append(test_vector,"Ineligibile")
  }
}
df$test=test_vector
sum(df$`Sampled Child`==df$test)

运行后会发现sum(df$Sampled Child==df$test)的结果远小于100,说明两列结果不一致。

核心原因

问题的本质不是赋值方式不同,而是在同一个循环迭代中连续调用了两次sample()函数:

  • R的随机数生成器是基于状态的,每次调用sample()(或其他随机函数如runif())都会消耗当前的随机数状态,生成下一个随机结果。
  • 你在给数据框列赋值时调用了一次sample(),紧接着给向量追加元素时又调用了一次相同参数的sample(),两次调用使用的是不同的随机数状态,自然得到不同的结果。
  • 额外说明:df$Sampled Child``初始为数值型,赋值字符串时会被强制转为字符型,但这只是数据类型的小问题,不影响结果不一致的核心逻辑。

修复方法

要让两个结果一致,只需将sample()的结果先存储到一个临时变量中,再用这个变量完成两次赋值操作,避免重复调用sample():

set.seed(26)
df$`Sampled Child`=0
test_vector=c()
for(i in 1:nrow(df)){
  childs_age = unlist(c(as.numeric(df[i,ages])))
  slice=which(childs_age<=17)
  if(length(slice)>=1){
    # 先获取一次采样结果,复用这个结果
    sampled_result <- sample(x=slice, size=1, replace = FALSE)
    df$`Sampled Child`[i] <- sampled_result
    test_vector <- append(test_vector, sampled_result)
  }
  else{
    df$`Sampled Child`[i] <- "Ineligibile"
    test_vector <- append(test_vector, "Ineligibile")
  }
}
df$test <- test_vector
sum(df$`Sampled Child`==df$test)  # 此时结果为100,两列完全一致

内容的提问来源于stack exchange,提问作者ssm1020

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 02:40:59