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

如何为数据框列表中符合条件的每行抽取Bernoulli分布结果?

问题描述

我需要在数据框列表中,对每个数据框里distance列值大于1000的每行,独立从伯努利分布(Bernoulli)中抽取0或1。但我怀疑当前代码是针对整个数据框生成分布结果,而非逐行处理,请问如何确认这一点?同时,我不清楚如何修改rbinom(length(distance),1,0.8),使其为符合条件的每行进行单次抽取。

当前代码:

mylistnew<-lapply(mylist, transform, outcome = ifelse(distance > 1000, 
rbinom(length(distance),1,0.8), NA))

数据子集:

list(structure(c(775.056695476403, 1414.15314106691, 2509.95923787194, 
1666.71143236238, 585.640129954299, 1169.17884175758, 152.505503148836, 
619.226302243787, 1263.66546590149, 1682.8712425131, -2.86809018002943, 
-2.87220511792857, -2.91236875367306, -2.91236875367306, -2.91137226768259, 
-2.91236875367306, -2.86275243787543, -2.8606012634912, -2.86264610888995, 
-2.86004943151114, 58.2523804031471, 58.2594633464797, 58.1998311185373, 
58.1998311185373, 58.1999333186371, 58.1998311185373, 58.243480631029, 
58.2359999509482, 58.2407966146843, 58.2335609045358, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1), .Dim = c(10L, 4L), .Dimnames = list(NULL, 
    c("distance", "lon", "lat", "ID"))), structure(c(775.056695476403, 
1414.15314106691, 2509.95923787194, 1666.71143236238, 585.640129954299, 
1169.17884175758, 152.505503148836, 619.226302243787, 1263.66546590149, 
1682.8712425131, -2.86809018002943, -2.87220511792857, -2.91236875367306, 
-2.91236875367306, -2.91137226768259, -2.91236875367306, -2.86275243787543, 
-2.8606012634912, -2.86264610888995, -2.86004943151114, 58.2523804031471, 
58.2594633464797, 58.1998311185373, 58.1998311185373, 58.1999333186371, 
58.1998311185373, 58.243480631029, 58.2359999509482, 58.2407966146843, 
58.2335609045358, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), .Dim = c(10L, 
4L), .Dimnames = list(NULL, c("distance", "lon", "lat", "ID"))))
解决方案

一、确认当前代码的问题

你的怀疑是对的,当前代码没有实现逐行独立抽取。核心原因是ifelse的运行逻辑:当第二个参数是一个向量时,ifelse会循环使用该向量的元素匹配条件为TRUE的行,若条件为TRUE的行数和向量长度不一致,就会重复取值,导致并非每行独立生成随机数。

验证步骤:

  1. 固定随机种子确保结果可复现:set.seed(123)
  2. 运行原代码后查看outcome列
  3. 观察所有distance>1000的行,会发现部分行的outcome值重复,这就证明代码没有逐行独立生成随机数。

二、修改代码的正确方式

以下两种方法都能实现仅对符合条件的每行独立抽取:

方法1:先初始化NA向量,再对目标行赋值

这种方法逻辑清晰,避免ifelse的潜在问题:

set.seed(123) # 可选,用于复现结果
mylistnew <- lapply(mylist, function(df) {
  df$outcome <- NA_real_ # 先将outcome列初始化为NA
  idx <- df$distance > 1000 # 筛选符合条件的行索引
  # 仅为符合条件的行生成伯努利随机数
  df$outcome[idx] <- rbinom(sum(idx), 1, 0.8)
  df
})

方法2:改进ifelse写法

若坚持使用ifelse,需让rbinom生成的随机数数量与数据框行数一致,确保每个行对应一个独立随机数:

set.seed(123)
mylistnew <- lapply(mylist, transform, 
                    outcome = ifelse(distance > 1000, 
                                     rbinom(nrow(.), 1, 0.8), 
                                     NA))

这里nrow(.)获取当前数据框的行数,生成对应长度的随机向量,ifelse会将每个随机数对应到每一行,实现逐行独立抽取。

三、验证修改后的结果

运行修改后的代码后,可通过以下命令查看结果:

# 查看第一个数据框的distance和outcome列
print(mylistnew[[1]][, c("distance", "outcome")])
  • distance<=1000的行outcome为NA
  • distance>1000的行outcome为0或1,且每个值都是独立生成的(重复运行代码结果会变化,固定种子则结果一致)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 19:31:02