如何将R语言flipCoinPoissonTimes函数运行100次并合并结果?
问题:重复运行抛硬币模拟函数并合并结果
我编写了flipCoinPoissonTimes()函数,模拟基于泊松分布的抛硬币实验,首次出现正面时停止并返回结果数据框。需要将该函数运行100次,把所有结果(包含iteration和total_turns列)合并为一个纵向数据框,但使用replicate(100, flipCoinPoissonTimes())未得到正确结果,求正确实现方法。
原函数代码如下:
flipCoinPoissonTimes <- function() { lambda <- 5 # initial parameter for the Poisson distribution num_flips <- rpois(1, lambda) # generate a random number from a Poisson distribution p <- 0.5 # initial probability of heads set <- 1 # initial set number results <- data.frame(set=integer(), turn_number=integer(), value_of_p=numeric(), result=character(), lambda=numeric(), num_flips=integer()) while(TRUE) { for (turn_number in 1:num_flips) { flip <- runif(1) # generate a random number between 0 and 1 if (flip < p) { results <- rbind(results, data.frame(set=set, turn_number=turn_number, value_of_p=p, result="Heads", lambda=lambda, num_flips=num_flips)) return(results) # stop once the first head is observed } else { results <- rbind(results, data.frame(set=set, turn_number=turn_number, value_of_p=p, result="Tails", lambda=lambda, num_flips=num_flips)) p <- p / 2 # reduce the probability of heads by half } } # if no heads were observed in this set, generate a new Poisson random number centered around the previous num_flips lambda <- num_flips num_flips <- rpois(1, lambda) p <- 0.5 # reset the probability of heads set <- set + 1 # increment the set number } }
解决方案
方法一:使用lapply循环处理并合并
replicate默认会尝试简化结果结构,导致数据框无法正确保留。改用lapply遍历迭代次数,每次生成结果后补充iteration和total_turns列,最后合并所有数据框:
# 运行100次并生成最终合并数据框 final_results <- do.call(rbind, lapply(1:100, function(iter) { # 调用模拟函数 res <- flipCoinPoissonTimes() # 添加迭代序号列 res$iteration <- iter # 添加本次实验的累计抛币次数列 res$total_turns <- 1:nrow(res) return(res) })) # 查看合并后的结果前几行 head(final_results)
方法二:用replicate生成列表后处理
如果坚持使用replicate,需要指定simplify=FALSE让它返回列表,再给每个列表元素补充信息后合并:
# 生成100次模拟结果的列表 sim_list <- replicate(100, flipCoinPoissonTimes(), simplify = FALSE) # 给每个结果添加迭代信息并合并 final_results <- do.call(rbind, mapply(function(res, iter) { res$iteration <- iter res$total_turns <- 1:nrow(res) res }, sim_list, 1:100, SIMPLIFY = FALSE))
两种方法最终都会得到一个包含所有100次实验结果的纵向数据框,其中:
iteration标记该记录属于第几次实验total_turns标记该记录是本次实验的第几次抛币
内容的提问来源于stack exchange,提问作者konofoso
相关产品推荐
相关产品推荐

