生成细胞计数随机的数据,但行总和始终相同

时间:2012-08-20 00:24:39

标签: r

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

>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 个答案:

答案 0 :(得分: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答案的一个版本,它使用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))

答案 1 :(得分: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

答案 2 :(得分: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 

等...

另外:

首先向其中一个数字添加一点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

答案 3 :(得分: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

如果您希望概率也是&#34;随机&#34;然后使用runif指定第一个,使用1 - that-value指定probs向量的第二个元素。