R中Monte Carlo模拟的加权随机抽样

Weighted random sampling for Monte Carlo simulation in R

我想运行一个Monte Carlo模拟。我有一个 data.frame,其中行是唯一 ID,有可能与其中一列相关联。输入到列中的数据可以视为该概率的权重。我想根据为每一行列出的权重随机 sample data.frame 中的每一行。每行应该只有 return 每个 运行 一个值。 data.frame 结构如下所示:

ID,    X2000,  X2001,  X2002,  X2003,  X2004
X11,   0,      0,      0.5,    0.5,    0
X33,   0.25,   0.25,   0.25,   0.25,   0
X55,   0,      0,      0,      0,      1
X77,   0.5,    0,      0,      0,      0.5

对于加权,"X11" 应该 return X2002 或 X2003,"X33" 应该具有相同的 returning X2000、X2001、X2002 或 X2003 的概率,应该是平等的,没有机会 returning X2004。 "X55" 唯一可能的 return 应该是 X2004。

我感兴趣的输出数据是 ID 和为此 运行 采样的列,尽管 return 可能更简单,如下所示:

ID,    X2000,  X2001,  X2002,  X2003,  X2004
X11,   0,      0,      1,      0,      0
X33,   1,      0,      0,      0,      0
X55,   0,      0,      0,      0,      1
X77,   1,      0,      0,      0,      0

您的 data.frame 已转置 - sample() 函数采用概率向量。但是,您的概率向量是按行排列的,这意味着很难从 data.frame.

中提取

要解决此问题 - 您可以将 ID 列导入为 row.name。这使您能够在 apply() 语句期间访问它。请注意 apply() 会将 data.frame 强制转换为矩阵,这意味着只允许一种数据类型。这就是为什么 ID 需要是行名的原因 - 否则我们会有一个字符概率向量而不是数字。

mc_df <- read.table(
text = 
'ID    X2000  X2001  X2002  X2003  X2004
X11   0      0      0.5    0.5    0
X33   0.25   0.25   0.25   0.25   0
X55   0      0      0      0      1
X77   0.5    0      0      0      0.5'
                    , header = T
                    ,row.names = 1)

从那里,可以使用应用功能:

apply(mc_df, 1, function(x) sample(names(x), size = 200, replace = T, prob = x))

或者你可以把它变得花哨

apply(mc_df, 1, function(x) table(sample(names(x), size = 200, replace = T, prob = x)))

$X11

X2002 X2003 
  102    98 

$X33

X2000 X2001 X2002 X2003 
   54    47    64    35 

$X55

X2004 
  200 

$X77

X2000 X2004 
  103    97 

发烧友:

apply(mc_df, 1, function(x) table(sample(as.factor(names(x)), size = 200, replace = T, prob = x)))
      X11 X33 X55 X77
X2000   0  51   0  99
X2001   0  50   0   0
X2002  91  57   0   0
X2003 109  42   0   0
X2004   0   0 200 101

或最奇特的:

prop.table(apply(mc_df
                 , 1
                 , function(x) table(sample(as.factor(names(x)), size = 200, replace = T, prob = x)))
           ,2)
       X11   X33 X55   X77
X2000 0.00 0.270   0 0.515
X2001 0.00 0.235   0 0.000
X2002 0.51 0.320   0 0.000
X2003 0.49 0.175   0 0.000
X2004 0.00 0.000   1 0.485