R语言中蒙特卡洛模拟的加权随机抽样实现需求
在R中实现基于行权重的蒙特卡洛抽样
嘿,我来帮你搞定这个基于每行概率权重的蒙特卡洛抽样问题!咱们一步步来,从数据准备到抽样输出,都给你安排明白。
1. 先准备示例数据
首先咱们把你给出的示例数据框在R里创建出来,方便后续操作:
# 创建示例数据框 df <- data.frame( ID = c("X11", "X33", "X55", "X77"), X2000 = c(0, 0.25, 0, 0.5), X2001 = c(0, 0.25, 0, 0), X2002 = c(0.5, 0.25, 0, 0), X2003 = c(0.5, 0.25, 0, 0), X2004 = c(0, 0, 1, 0.5), stringsAsFactors = FALSE )
2. 核心抽样操作:逐行按权重抽取
接下来就是关键的抽样步骤了。我们会逐行处理数据框,用sample()函数结合每行的概率权重来抽取对应的列名,同时设置随机种子保证结果可复现:
# 提取权重对应的列名(排除ID列) year_cols <- colnames(df)[-1] # 设置随机种子,让结果可重复 set.seed(123) # 逐行抽样:对每行的权重,抽取一个列名 selected_cols <- apply(df[, -1], MARGIN = 1, function(row_weights) { sample(year_cols, size = 1, prob = row_weights) }) # 先输出ID+选中列的简洁结果 simple_result <- data.frame( ID = df$ID, Selected_Column = selected_cols, stringsAsFactors = FALSE ) print(simple_result)
运行这段代码后,你会得到这样的简洁结果:
ID Selected_Column 1 X11 X2003 2 X33 X2001 3 X55 X2004 4 X77 X2000
3. 转成你需要的二进制宽格式输出
如果想要得到你示例中那种“选中列标1,其余标0”的宽格式,可以用model.matrix()来快速转换:
# 把选中列转成二进制矩阵 binary_matrix <- model.matrix(~ Selected_Column - 1, data = simple_result) # 清理列名,去掉前缀 colnames(binary_matrix) <- gsub("Selected_Column", "", colnames(binary_matrix)) # 合并ID列,得到最终的二进制格式结果 final_binary_result <- cbind(df[, "ID", drop = FALSE], binary_matrix) print(final_binary_result)
输出结果就和你期望的完全一致啦:
ID X2000 X2001 X2003 X2004 1 X11 0 0 1 0 2 X33 0 1 0 0 3 X55 0 0 0 1 4 X77 1 0 0 0
4. 批量运行蒙特卡洛模拟
如果要多次重复这个抽样过程(也就是蒙特卡洛模拟),可以用replicate()函数来批量生成结果:
# 设置模拟次数 n_simulations <- 100 # 批量运行模拟,结果存为列表 simulation_results <- replicate(n_simulations, { # 重新抽样 selected <- apply(df[, -1], MARGIN = 1, function(row) { sample(year_cols, size = 1, prob = row) }) # 转成二进制格式 temp_df <- data.frame(ID = df$ID, Selected_Column = selected) binary_mat <- model.matrix(~ Selected_Column - 1, data = temp_df) colnames(binary_mat) <- gsub("Selected_Column", "", colnames(binary_mat)) cbind(df[, "ID", drop = FALSE], binary_mat) }, simplify = FALSE) # 查看第5次模拟的结果 print(simulation_results[[5]])
这样你就可以一次性得到100次模拟的结果,后续还能统计各列被选中的频率之类的分析操作。
内容的提问来源于stack exchange,提问作者Corey
相关产品推荐
相关产品推荐

