5

我处于需要创建一堆假数据集的情况,其中两个变量的总和与我的真实数据相同,但每个变量的计数是随机的。这是设置:

>df
    X.1  X.2
1   145   30
2    55   73   

第一行总和为 175,第二行总和为 128。我正在寻找的是一种生成数据帧(或一堆数据帧)的方法,如下所示:

>df.2
    X.1  X.2
1   100   75
2    90   38

在 df.2 中,单元格计数发生了变化,但行仍然汇总到同一个表中。实际数据有数百行,但如果有帮助的话,只有两个变量。我试图弄清楚如何做到这一点,sample()但没有任何运气。有什么建议么?

谢谢!

4

4 回答 4

6

也许您正在寻找r2dtable

> r2dtable(2, c(175,128), c(190, 113))
[[1]]
     [,1] [,2]
[1,]  108   67
[2,]   82   46

[[2]]
     [,1] [,2]
[1,]  114   61
[2,]   76   52

此外,这是@mnel's answer的一个版本,用于rmultinom进行n复制然后组合结果。如果您只需要一些复制,这并不重要,但既然rmultinom可以做到,我想我会看看它是如何完成的。

n <- 10
e <- cbind(X1  = c(100,90,30),X2 = c(75,28,120))
aperm(array(sapply(1:nrow(e), function(i) 
        rmultinom(n, rowSums(e)[i], (e/rowSums(e))[i,])),
      dim=c(ncol(e),n,nrow(e))), c(3,1,2))
于 2012-08-20T01:59:32.737 回答
5

您正在从多项分布中抽样,


编辑

允许预先指定的预期细胞计数

  • 多项分布可以将每个单元视为泊松分布(具有预期单元计数),以总和为条件。

编辑 2

  • 允许任意数量的行/预期的单元格计数
  • expected作为预期的细胞计数通过

请注意,它rmultinom返回一个矩阵,其中每列都是多项式样本,因此我使用它t来创建单行矩阵

replicates <- 10
expected <- data.frame(X1  = c(100,90,30),X2 = c(75,28,120))
##    X1  X2
## 1 100  75
## 2  90  28
## 3  30 120
data_samples <- lapply(seq(replicates), function(i, expected){
   # create a list of expected cell counts (list element = row of expected)
  .list <- lapply(apply(expected,1,list),unlist)
   # sample from these expected cell counts and recombine into a data.frame
   as.data.frame(do.call(rbind,lapply(.list, function(.x) t(rmultinom(n = 1, prob = .x,  size = sum(.x) )))))
   }, expected = expected)

这将创建一个data.frames具有适当属性的列表

data_samples[[1]]
##    X1  X2
## 1 104  71
## 2  84  34
## 3  19 131


data_samples[[5]]
##   X1  X2
## 1 88  87
## 2 92  26
## 3 27 123
于 2012-08-20T00:44:07.873 回答
2

答案中使用的数据:

test <- data.frame(X.1=c(145,55),X.2=c(30,73))

使用的版本sample

t(sapply(
        rowSums(test),
        function(x) {
                one <- sample(1:x,1)
                two <- (x - one)
                result <- data.frame(one,two)
                names(result) <- names(test)
                return(result)
                }
         )
)

结果如下所示:

     X.1 X.2
[1,] 20  155
[2,] 127 1  

或者...

     X.1 X.2
[1,] 111 64 
[2,] 94  34 

ETC...

或者:

只需jitter先在其中一个数字上加一点,然后从行总和中减去。

t(apply(
        test,
        1,
        function(x) {
                rsum <- sum(x)
                one <- round(jitter(x[1],20,20),0)
                two <- (rsum - one)
                result <- c(one,two)
                names(result) <- names(test)
                return(result)
                }
    )
)

结果示例:

     X.1 X.2
[1,] 160  15
[2,]  47  81

     X.1 X.2
[1,] 127  48
[2,]  64  64
于 2012-08-20T00:59:35.387 回答
0

如果您的总样本量为 n= .. 说 40 并且单元格数是 4 列数 = 说 2 那么调用应该是:

rmultinom(2, size = 40/4, prob = c(0.5,0.5))
     [,1] [,2]
[1,]    6    3
[2,]    4    7

如果您想要一个函数以每行指定的概率提供这种结果,那么:

 my_mat_rand <- function(tot, coln, probs){
     rmultinom(coln, size = tot/length(probs), prob = probs) }

> my_mat_rand(tot=40, coln=2, probs  = c(0.5,0.5))
     [,1] [,2]
[1,]   11   10
[2,]    9   10
> my_mat_rand(40, 2, probs  = c(0.5,0.5))
     [,1] [,2]
[1,]    8   13
[2,]   12    7

如果您希望概率也是“随机的”,则使用runif指定第一个元素和 1-指定向量that-value的第二个元素。probs

于 2017-06-15T04:57:29.610 回答