我有这样的数据帧(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的帮助,感谢我之前关于随机化两列的问题的回答。
答案 0 :(得分:206)
鉴于R data.frame:
> df1
a b c
1 1 1 0
2 1 0 0
3 0 1 0
4 0 0 0
随机播放:
> 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(...)
可确保在没有替换的情况下完成抽样,从而实现行方式的随机播放。
随机播放:
> 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
答案 1 :(得分:10)
查看素食主义包中的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
足够长,那么很可能会发生这种情况。此外,您可以绘制比您需要的更多随机矩阵,并丢弃不符合您所有要求的矩阵。
您要求每行有不同数量的更改,此处也未涉及。您可以再次采样比您想要的更多的矩阵,然后丢弃那些不符合此要求的矩阵。
答案 2 :(得分:9)
这是使用包data.frame
随机播放dplyr
的另一种方式:
行方向:
df2 <- slice(df1, sample(1:n()))
或
df2 <- sample_frac(df1, 1L)
逐列:
df2 <- select(df1, one_of(sample(names(df1))))
答案 3 :(得分:5)
您还可以使用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
答案 4 :(得分:4)
当然,您可以对每一行进行采样:
sapply (1:4, function (row) df1[row,]<<-sample(df1[row,]))
将自行调整行,因此每行中1
的数量不会改变。小的变化,它也适用于列,但这是一个练习给读者:-P
答案 5 :(得分:1)
您还可以使用以下方法在数据框中“采样”相同数量的项目:
nr<-dim(M)[1]
random_M = M[sample.int(nr),]
答案 6 :(得分:0)
数据帧中的随机样本和排列 如果是以矩阵形式转换为data.frame 使用基础包中的示例函数 indices = sample(1:nrow(df1),size = 1 * nrow(df1)) 随机样本和排列
答案 7 :(得分:0)
如果目标是随机地对每一列进行洗牌,则上述某些答案将无效,因为这些列被一起洗牌了(这保留了列间的相关性)。其他人则需要安装软件包。然而,只有一种情况:
df2 = lapply(df1, function(x) { sample(x) })