【问题标题】:Generate a random distribution by group conditional on a column以列为条件按组生成随机分布
【发布时间】:2020-11-19 14:11:48
【问题描述】:

我想以列为条件生成两个不同的分布。例如,如果z1 大于 25,我生成正态分布rnorm(),否则生成泊松rpois()。此外,我想从规定的分布中获得按组(列id)的变化。

现在我有以下代码:

df <- structure(list(id = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
                      4L, 4L), z1 = c(21L, 21L, 21L, 28L, 28L, 28L, 30L, 30L, 30L, 
                                      20L, 20L, 20L)), row.names = c(NA, -12L), class = "data.frame")  
  
df$sample  <- with(df, ifelse(z1 > 25, 
                         rnorm(n = 1,mean = 0,sd = 1), ##Normal(0,1)
                         rpois(n = 1,lambda = 5)))     ## Poisson(5) 

  # id z1     sample
  # 1   1 21  6.0000000
  # 2   1 21  6.0000000
  # 3   1 21  6.0000000
  # 4   2 28 -0.8036847
  # 5   2 28 -0.8036847
  # 6   2 28 -0.8036847
  # 7   3 30 -0.8036847
  # 8   3 30 -0.8036847
  # 9   3 30 -0.8036847
  # 10  4 20  6.0000000
  # 11  4 20  6.0000000
  # 12  4 20  6.0000000

不幸的是,正如您在上面看到的那样我没有在 id 组中看到变化id 列)。 以下是desired_sample 列中我想要的输出。

  
  #     id z1     sample     desired_sample
  # 1   1 21  6.0000000  5.0000000
  # 2   1 21  6.0000000  5.0000000
  # 3   1 21  6.0000000  5.0000000
  # 4   2 28 -0.8036847  0.7356226
  # 5   2 28 -0.8036847  0.7356226
  # 6   2 28 -0.8036847  0.7356226
  # 7   3 30 -0.8036847 -1.359669
  # 8   3 30 -0.8036847 -1.359669
  # 9   3 30 -0.8036847 -1.359669
  # 10  4 20  6.0000000  4.0000000
  # 11  4 20  6.0000000  4.0000000
  # 12  4 20  6.0000000  4.0000000

[跟进]

下面的代码可以做到,但是...

con_dist2 <- function(x){
  ifelse( x>=25,
          return(rnorm(1,mean = 0 , sd = 1 )),
          return(rpois(1,lambda = 5 )))
}

df$desired_sample2<- with(df ,ave(x = z1, id, FUN = con_dist2), )

...有什么方法可以将阈值(25)作为函数con_dist2 输入,使其更加灵活和可重用?

【问题讨论】:

  • 是的,对不起。我将编辑我的问题。我的意思是我没有在组ID(列ID)中得到变化。更准确地说,我希望每个段(由z1&gt;25z1&lt;=25 定义)的值是来自同一分布的不同抽取(每个段不同)。现在有意义吗?
  • 先试试这个函数myfun &lt;- function(x) { y &lt;- ifelse(x &gt; 25,rnorm(n = 1,mean = 0,sd = 1),rpois(n = 1,lambda = 5)) return(y) } 然后这个代码:df$Sample &lt;- apply(df['z1'],1,myfun)
  • 非常感谢@Duck,我刚刚发布了一篇后续文章,其结构与您提议的结构非常相似。最后,有没有办法将阈值(25)作为myfun 的输入,使其更加灵活和可重用?
  • 我为新语句添加了一个可能的解决方案。让我知道这是否适合你。您必须在函数中添加一个新参数。
  • 我添加了一个带有另一个参数的示例,以便您了解它是如何工作的。我希望这对你有帮助。如果答案帮助您考虑可能接受它。非常感谢!

标签: r if-statement random aggregate sampling


【解决方案1】:

在您的代码上尝试此更改:

#Function
con_dist2 <- function(x,n){
  ifelse( x>=n,
          return(rnorm(1,mean = 0 , sd = 1 )),
          return(rpois(1,lambda = 5 )))
}
#Apply
df$desired_sample2<- with(df ,ave(x = z1, id, FUN = function(x) con_dist2(x,n=25)) )

更多参数试试这个:

#Function 2
con_dist2 <- function(x,n,mymean){
  ifelse( x>=n,
          return(rnorm(1,mean = mymean , sd = 1 )),
          return(rpois(1,lambda = 5 )))
}
#Apply 2
df$desired_sample2<- with(df ,ave(x = z1, id, FUN = function(x) con_dist2(x,n=25,mymean = 0)) )

【讨论】: