首页 文章

如何按行和列方式随机化(或置换)数据帧?

提问于
浏览
69

我有这样的数据帧(df1) .

f1   f2   f3   f4   f5
d1   1    0    1    1    1  
d2   1    0    0    1    0
d3   0    0    0    1    1
d4   0    1    0    0    1

d1 ... d4列是rowname,f1 ... f5行是列名 .

为了做样本(df1),我得到一个与df1相同的新数据帧 . 因此,对于整个数据帧,计数为1,但对于每行或每列,都不是 .

是否可以逐行或逐列进行随机化?

我想为每列按列随机化df1,即每列中的1的数量保持不变 . 每列需要更改至少一次 . 例如,我可能有一个像这样的随机df2 :(注意每列中的1的计数保持不变,但每行中的计数为1不同 .

f1   f2   f3   f4   f5
d1   1    0    0    0    1  
d2   0    1    0    1    1
d3   1    0    0    1    1
d4   0    0    1    1    0

同样,我也想为每一行按行随机化df1,即no . 每行中1的值保持不变,并且每行都需要更改(但更改的条目的数量可能不同) . 例如,随机化的df3可能是这样的:

f1   f2   f3   f4   f5
d1   0    1    1    1    1  <- two entries are different
d2   0    0    1    0    1  <- four entries are different
d3   1    0    0    0    1  <- two entries are different
d4   0    0    1    0    1  <- two entries are different

PS . 非常感谢Gavin Simpson,Joris Meys和Chase的帮助,以回答我之前关于随机化两列的问题的回答 .

7 回答

  • 5

    鉴于R data.frame:

    > df1
      a b c
    1 1 1 0
    2 1 0 0
    3 0 1 0
    4 0 0 0
    

    Shuffle row-wise:

    > df2 <- df1[sample(nrow(df1)),]
    > df2
      a b c
    3 0 1 0
    4 0 0 0
    2 1 0 0
    1 1 1 0
    

    默认情况下 sample() 随机重新排序作为第一个参数传递的元素 . 这意味着默认大小是传递的数组的大小 . 将参数 replace=FALSE (默认值)传递给 sample(...) 可确保在没有替换的情况下完成采样,从而实现行方式的随机播放 .

    Shuffle column-wise:

    > df3 <- df1[,sample(ncol(df1))]
    > df3
      c a b
    1 0 1 1
    2 0 1 0
    3 0 0 1
    4 0 0 0
    
  • 10

    看一下 vegan 包中的 permatswap() . 这是一个维护行和列总计的示例,但您可以放松它并仅修复行或列总和中的一个 .

    mat <- matrix(c(1,1,0,0,0,0,0,1,1,0,0,0,1,1,1,0,1,0,1,1), ncol = 5)
    set.seed(4)
    out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab")
    

    这给出了:

    R> out$perm[[1]]
         [,1] [,2] [,3] [,4] [,5]
    [1,]    1    0    1    1    1
    [2,]    0    1    0    1    0
    [3,]    0    0    0    1    1
    [4,]    1    0    0    0    1
    R> out$perm[[2]]
         [,1] [,2] [,3] [,4] [,5]
    [1,]    1    1    0    1    1
    [2,]    0    0    0    1    1
    [3,]    1    0    0    1    0
    [4,]    0    0    1    0    1
    

    解释电话:

    out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab")
    
    • times 是你想要的随机矩阵的数量,这里是99

    • burnin 是我们开始随机抽样之前进行的互换次数 . 在我们开始采用每个随机矩阵之前,这允许我们采样的矩阵是非常随机的

    • thin 表示每隔 thin 交换一次随机抽取

    • mtype = "prab" 表示将矩阵视为存在/不存在,即二进制0/1数据 .

    有几点需要注意,这并不保证任何列或行都是随机的,但如果 burnin 足够长,那么很有可能发生这种情况 . 此外,您可以绘制比您需要的更多随机矩阵,并丢弃不符合您所有要求的矩阵 .

    您要求每行具有不同数量的更改,此处也未涉及 . 您可以再次采样比您想要的更多的矩阵,然后丢弃那些不符合此要求的矩阵 .

  • 195

    这是使用包 dplyr 来改变 data.frame 的另一种方法:

    按行:

    df2 <- slice(df1, sample(1:n()))
    

    要么

    df2 <- sample_frac(df1, 1L)
    

    逐列:

    df2 <- select(df1, one_of(sample(names(df1))))
    
  • 6

    你也可以在R包中使用 randomizeMatrix 函数 picante

    例:

    test <- matrix(c(1,1,0,1,0,1,0,0,1,0,0,1,0,1,0,0),nrow=4,ncol=4)
    > test
         [,1] [,2] [,3] [,4]
    [1,]    1    0    1    0
    [2,]    1    1    0    1
    [3,]    0    0    0    0
    [4,]    1    0    1    0
    
    randomizeMatrix(test,null.model = "frequency",iterations = 1000)
    
         [,1] [,2] [,3] [,4]
    [1,]    0    1    0    1
    [2,]    1    0    0    0
    [3,]    1    0    1    0
    [4,]    1    0    1    0
    
    randomizeMatrix(test,null.model = "richness",iterations = 1000)
    
         [,1] [,2] [,3] [,4]
    [1,]    1    0    0    1
    [2,]    1    1    0    1
    [3,]    0    0    0    0
    [4,]    1    0    1    0
    >
    

    选项 null.model="frequency" 维护列总和, richness 维护行总和 . 虽然主要用于在社区生态学中随机化物种存在缺失数据集,但它在这里运作良好 .

    此函数还有其他空模型选项,请查看以下链接以获取picante documentation的更多详细信息(第36页)

  • 0

    当然你可以对每一行进行采样:

    sapply (1:4, function (row) df1[row,]<<-sample(df1[row,]))
    

    将自动改变行,所以 1 's in each row doesn'的数量会改变 . 小的变化,它也适用于列,但这是一个练习给读者:-P

  • 4

    数据框中的随机样本和排列如果是矩阵形式转换为data.frame,请使用基础包中的样本函数indices = sample(1:nrow(df1),size = 1 * nrow(df1))随机样本和排列

  • 0

    您还可以使用以下内容“抽样”数据框中相同数量的项目:

    nr<-dim(M)[1]
    random_M = M[sample.int(nr),]
    

相关问题