【问题标题】:Generate distribution based on mean and sd multiple times for different groups为不同的组多次生成基于均值和标准差的分布
【发布时间】:2019-05-06 18:10:00
【问题描述】:

我有一个由分组变量、均值和标准差组成的数据框。我想根据每个组的组均值和标准差为每个组生成多个均值(例如 10 个)。我可以使用 rnorm 和 dplyr 函数“mutate”来做到这一点,但我在多次执行此操作并将列表编译成带有标记复制的数据帧时遇到了麻烦。

Group = c("A","B","C","D","E") 
Mean = c(1.25,5.5,3.25,1,5) 
SD = c(2.5,3,2.25,2,5.35) 
df = data.frame(Group,Mean,SD)

df

#works for one rep
df%>%
  group_by(Group)%>%
  mutate(est_mean=rnorm(1,mean=Mean,sd=SD))

#replicated 10 times but in list form
replicate(10, df%>%
        group_by(Group)%>%
        mutate(est_mean=rnorm(1,mean=Mean,sd=SD)))

块引用

最终我希望得到一个数据帧,其中包含组、平均值、标准差、估计平均值和基于重复数的 ID 号(在本例中为 1 到 10)。下面是前 5 行的示例。

Group  Mean    SD      est_mean  ID
 A     1.25   2.50     3.07      1
 B     5.50   3.00     7.64      1
 C     3.25   2.25     2.90      1
 D     1.00   2.00     0.11      1
 E     5.00   5.35     1.03      1

【问题讨论】:

    标签: r list dplyr replicate


    【解决方案1】:

    如果我正确理解了您的问题,您是否希望以不同的方式为每个组生成 10 次相同的 df,10 次不同的时间?如果是这样,这里有一个稍微笨拙的方法来完成这样的事情:

    library(tidyverse)
    
    set.seed(123)
    
    Group = c("A","B","C","D","E") 
    Mean = c(1.25,5.5,3.25,1,5) 
    SD = c(2.5,3,2.25,2,5.35) 
    df = data.frame(Group,Mean,SD)
    
    df
    #>   Group Mean   SD
    #> 1     A 1.25 2.50
    #> 2     B 5.50 3.00
    #> 3     C 3.25 2.25
    #> 4     D 1.00 2.00
    #> 5     E 5.00 5.35
    
    map_df(1:10, ~df) %>% 
        mutate(ID = rep(1:10, each=5),
               est_mean = map2(Mean, SD, ~rnorm(1, .x, .y)))
    #>    Group Mean   SD ID   est_mean
    #> 1      A 1.25 2.50  1 -0.1511891
    #> 2      B 5.50 3.00  1   4.809468
    #> 3      C 3.25 2.25  1   6.757094
    #> 4      D 1.00 2.00  1   1.141017
    #> 5      E 5.00 5.35  1   5.691689
    #> 6      A 1.25 2.50  2   5.537662
    #> 7      B 5.50 3.00  2   6.882749
    #> 8      C 3.25 2.25  2  0.4036122
    #> 9      D 1.00 2.00  2 -0.3737057
    #> 10     E 5.00 5.35  2   2.615708
    #> 11     A 1.25 2.50  3   4.310204
    #> 12     B 5.50 3.00  3   6.579441
    #> 13     C 3.25 2.25  3   4.151736
    #> 14     D 1.00 2.00  3   1.221365
    #> 15     E 5.00 5.35  3    2.02625
    #> 16     A 1.25 2.50  4   5.717283
    #> 17     B 5.50 3.00  4   6.993551
    #> 18     C 3.25 2.25  4  -1.174889
    #> 19     D 1.00 2.00  4   2.402712
    #> 20     E 5.00 5.35  4   2.470566
    #> 21     A 1.25 2.50  5  -1.419559
    #> 22     B 5.50 3.00  5   4.846075
    #> 23     C 3.25 2.25  5    0.94149
    #> 24     D 1.00 2.00  5 -0.4577825
    #> 25     E 5.00 5.35  5    1.65604
    #> 26     A 1.25 2.50  6  -2.966733
    #> 27     B 5.50 3.00  6   8.013361
    #> 28     C 3.25 2.25  6    3.59509
    #> 29     D 1.00 2.00  6  -1.276274
    #> 30     E 5.00 5.35  6   11.70791
    #> 31     A 1.25 2.50  7   2.316161
    #> 32     B 5.50 3.00  7   4.614786
    #> 33     C 3.25 2.25  7   5.264033
    #> 34     D 1.00 2.00  7   2.756267
    #> 35     E 5.00 5.35  7   9.395459
    #> 36     A 1.25 2.50  8   2.971601
    #> 37     B 5.50 3.00  8   7.161753
    #> 38     C 3.25 2.25  8   3.110699
    #> 39     D 1.00 2.00  8  0.3880747
    #> 40     E 5.00 5.35  8    2.96448
    #> 41     A 1.25 2.50  9 -0.4867674
    #> 42     B 5.50 3.00  9   4.876248
    #> 43     C 3.25 2.25  9  0.4028582
    #> 44     D 1.00 2.00  9   5.337912
    #> 45     E 5.00 5.35  9    11.4626
    #> 46     A 1.25 2.50 10  -1.557771
    #> 47     B 5.50 3.00 10   4.291345
    #> 48     C 3.25 2.25 10   2.200025
    #> 49     D 1.00 2.00 10    2.55993
    #> 50     E 5.00 5.35 10   4.553975
    

    reprex package (v0.2.1) 于 2019 年 5 月 6 日创建

    【讨论】:

    • 感谢您的帮助,我喜欢您的代码的简单性。效果很好!
    • @RyanStephens 很高兴我能帮上忙。请记住接受我的回答,以便将来有相同问题的其他人知道。谢谢。
    【解决方案2】:

    我提出了另一个没有dplyr 的答案,但我有义务处理数据类型。但是我可以模拟 10 个随机变量而无需调用 10 次 rnorm 函数。不知道是1次模拟调用10次更好,还是10次模拟调用一次更好。

    问题数据:

    Group = c("A","B","C","D","E") 
    Mean = c(1.25,5.5,3.25,1,5) 
    SD = c(2.5,3,2.25,2,5.35) 
    df = data.frame(Group, Mean, SD)
    

    我的代码如下:

    m <- length(Mean)
    p <- 10
    res <- data.frame(factor("A", level=Group), matrix(0, nrow=m*p, ncol=4))
    res[,1] <- rep(Group, each = p)
    res[,2] <- rep(Mean, each = p)
    res[,3] <- rep(SD, each = p)
    res[,4] <- matrix(apply(df, 1, function(row, p){
      rnorm(p, mean=as.numeric(row[2]), sd=as.numeric(row[3]))}, p = p), nrow=p*m, ncol=1)
    res[,5] <- rep(seq(1, p), m)
    
    colnames(res) = c("Group", "Mean", "SD", "Est_Mean", "Indices")
    res = res[order(res$Indices), ]
    

    【讨论】: