2011-06-21 68 views
56

我有一個像這樣的數據框(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逐行,也就是每行中的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非常感謝來自加文·辛普森,里斯Meys和大通幫助以前的答案,我剛纔的問題上隨機兩列

+0

你想在同一時間來排列都行*和*列。重讀這個,它看起來像列約束(每列中1的數目相同)在你的第二個例子排列行中沒有。 –

+0

請不要註冊多個帳戶。我已要求版主將您在此處使用的帳戶與前一版Q中使用的帳戶合併。 –

回答

4

當然,你可以品嚐到每一行:

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

洗牌行本身,所以1的每一行的數量不會改變。小的變化,它也適用於列,但這是一個爲讀者的練習:-P

+2

沒有任何內容試圖實施OP希望施加的約束。 –

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") 
  1. times是你想要的隨機矩陣的數量,這裏99
  2. burnin是多少在我們開始採取隨機山姆之前進行掉期普萊斯。這讓我們從中採樣矩陣是相當隨機的,然後纔開始服用,每次我們隨機矩陣的
  3. thin說,只有採取隨機抽籤的每thin互換
  4. mtype = "prab"說對待矩陣存在/不存在,即二進制0/1數據。

幾件事情要注意,這並不能保證任何列或行已隨機的,但如果burnin是足夠長的時間,應該是具有發生了一個很好的機會。此外,您可以繪製比您需要的更多隨機矩陣,並丟棄不符合您所有要求的矩陣。

您的要求每行有不同數量的更改,這裏也不介紹。再次,您可以抽取比您想要的更多矩陣,然後丟棄那些不符合此要求的矩陣。

173

列出的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 
+4

我認爲這很有趣,這不是最重要的評論,但它比去學習其他一些軟件包更簡單。幾乎所有關於排列的問題都是如此。只需使用SAMPLE()! –

+0

我是否正確假設這個方法會維護row.names? –

+0

使用=超過標準< - 在這種情況下的任何原因? – Christian

5

,你也可以使用randomizeMatrix功能在R包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

0

隨機樣本和排列INA數據幀 的更多細節(第36頁)如果是矩陣形式轉換成data.frame 使用示例函數從基部包 索引=樣品(1:nrow(DF1),大小= 1 * nrow(DF1)) 隨機樣本和排列

0

這是另一種使用包dplyr洗牌data.frame

逐行:

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

df2 <- sample_frac(df1, 1L) 

逐列:

df2 <- select(df1, one_of(sample(names(df1)))) 
相關問題