Làm thế nào để ngẫu nhiên hóa (hoặc hoán vị) một rowwise khung dữ liệu và theo chiều cột?


96

Tôi có một khung dữ liệu (df1) như thế này.

     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

Cột d1 ... d4 là tên hàng, hàng f1 ... f5 là tên cột.

Để làm mẫu (df1), tôi nhận được một khung dữ liệu mới với số lượng là 1 giống như df1. Vì vậy, số lượng 1 được bảo toàn cho toàn bộ khung dữ liệu chứ không phải cho từng hàng hoặc từng cột.

Có thể thực hiện ngẫu nhiên hóa theo hàng hoặc theo cột không?

Tôi muốn ngẫu nhiên hóa cột df1 cho mỗi cột, tức là số 1 trong mỗi cột vẫn giữ nguyên. và mỗi cột cần được thay đổi ít nhất một lần. Ví dụ, tôi có thể có một df2 ngẫu nhiên như thế này: (Lưu ý rằng số 1 trong mỗi cột vẫn như nhau nhưng số 1 trong mỗi hàng là khác nhau.

     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

Tương tự như vậy, tôi cũng muốn ngẫu nhiên hóa hàng df1 cho mỗi hàng, tức là số không. của 1 trong mỗi hàng vẫn giữ nguyên và mỗi hàng cần phải được thay đổi (nhưng không có mục nào đã thay đổi có thể khác). Ví dụ: một df3 ngẫu nhiên có thể giống như sau:

     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

Tái bút. Rất cám ơn sự giúp đỡ từ Gavin Simpson, Joris Meys và Chase cho các câu trả lời trước đây cho câu hỏi trước của tôi về việc sắp xếp ngẫu nhiên hai cột.


bạn có muốn hoán vị cả hàng cột cùng một lúc. Đọc lại điều này, có vẻ như ràng buộc cột (cùng số 1 trong mỗi cột) không được giữ trong các hàng hoán vị ví dụ thứ hai của bạn.
Gavin Simpson

1
Vui lòng không đăng ký nhiều tài khoản. Tôi đã hỏi những người kiểm duyệt để hợp nhất các tài khoản mà bạn sử dụng ở đây với một sử dụng trên Q. trước
Gavin Simpson

Câu trả lời:


233

Với khung dữ liệu R:

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

Trộn hàng một cách khôn ngoan:

> 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

Theo mặc định, sample()sắp xếp lại ngẫu nhiên các phần tử được truyền làm đối số đầu tiên. Điều này có nghĩa là kích thước mặc định là kích thước của mảng được truyền vào. Truyền tham số replace=FALSE(mặc định) để sample(...)đảm bảo rằng việc lấy mẫu được thực hiện mà không cần thay thế, điều này hoàn thành việc xáo trộn hàng một cách khôn ngoan.

Trộn cột khôn ngoan:

> 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

5
Tôi nghĩ thật buồn cười khi đây không phải là bình luận hàng đầu, và nó đơn giản hơn là đi và tìm hiểu về một số gói khác. Điều đó đúng với hầu hết mọi câu hỏi về hoán vị. CHỈ SỬ DỤNG SAMPLE ()!
Cân bằng Brash 14/10/12

Tôi có đúng khi giả định rằng phương pháp này sẽ duy trì row.names không?
tumultous_rooster,

Bất kỳ lý do nào để sử dụng = over the standard <- trong trường hợp này?
Christian

4
Vâng, điều này đang thay đổi thứ tự của các hàng và cột, nhưng những gì OP muốn là khác nhau: xáo trộn mỗi cột / hàng độc lập
JelenaČuklina

chính xác những gì tôi cần!
ChuckCottrill

18

Đây là một cách khác để xáo trộn data.framegói đang sử dụng dplyr:

khôn ngoan:

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

hoặc là

df2 <- sample_frac(df1, 1L)

chuyên mục khôn ngoan:

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

10

Hãy xem permatswap()trong gói thuần chay . Đây là một ví dụ duy trì cả tổng hàng và cột, nhưng bạn có thể nới lỏng điều đó và chỉ sửa một trong các tổng của hàng hoặc cột.

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")

Điều này mang lại:

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

Để giải thích cuộc gọi:

out <- permatswap(mat, times = 99, burnin = 20000, thin = 500, mtype = "prab")
  1. times là số ma trận ngẫu nhiên mà bạn muốn, ở đây là 99
  2. burninlà số lần hoán đổi được thực hiện trước khi chúng tôi bắt đầu lấy mẫu ngẫu nhiên. Điều này cho phép ma trận mà từ đó chúng tôi lấy mẫu khá ngẫu nhiên trước khi chúng tôi bắt đầu lấy từng ma trận ngẫu nhiên của chúng tôi
  3. thincho biết chỉ rút thăm ngẫu nhiên mỗi lần thinhoán đổi
  4. mtype = "prab" nói rằng hãy coi ma trận là sự hiện diện / vắng mặt, tức là dữ liệu 0/1 nhị phân.

Một vài điều cần lưu ý, điều này không đảm bảo rằng bất kỳ cột hoặc hàng nào đã được ngẫu nhiên hóa, nhưng nếu burninđủ dài thì rất có thể điều đó đã xảy ra. Ngoài ra, bạn có thể vẽ nhiều ma trận ngẫu nhiên hơn bạn cần và loại bỏ những ma trận không phù hợp với tất cả các yêu cầu của bạn.

Yêu cầu của bạn để có số lượng thay đổi khác nhau trên mỗi hàng, cũng không được đề cập ở đây. Một lần nữa, bạn có thể lấy mẫu nhiều ma trận hơn bạn muốn và sau đó loại bỏ những ma trận không đáp ứng yêu cầu này.


6

bạn cũng có thể sử dụng randomizeMatrixchức năng trong gói Rpicante

thí dụ:

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
> 

Tùy chọn null.model="frequency"duy trì tổng cột và richnessduy trì tổng hàng. Mặc dù chủ yếu được sử dụng để ngẫu nhiên hóa các bộ dữ liệu về sự vắng mặt của loài trong sinh thái cộng đồng, nó hoạt động tốt ở đây.

Chức năng này cũng có các tùy chọn mô hình rỗng khác, hãy xem liên kết sau để biết thêm chi tiết (trang 36) của tài liệu picante


4

Tất nhiên, bạn có thể lấy mẫu từng hàng:

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

sẽ tự xáo trộn các hàng, vì vậy số lượng của 1mỗi hàng không thay đổi. Những thay đổi nhỏ và nó cũng hoạt động tốt với các cột, nhưng đây là một bài tập cho người đọc :-P


2
Không có gì trong đó cố gắng thực hiện các ràng buộc mà OP muốn áp đặt.
Gavin Simpson

2

Bạn cũng có thể "lấy mẫu" cùng một số mục trong khung dữ liệu của mình với một cái gì đó như sau:

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

thay vào đó dim(M)[1], bạn có thể sử dụng nrow(M)để toàn bộ quy trình trở thành một lớp lót:random_M <- M[nrow(M),]
Agile Bean

1

Nếu mục tiêu là xáo trộn ngẫu nhiên từng cột, một số câu trả lời ở trên không hoạt động vì các cột được xáo trộn cùng nhau (điều này bảo toàn tương quan giữa các cột). Những người khác yêu cầu cài đặt một gói. Tuy nhiên, tồn tại một lớp lót:

df2 = lapply(df1, function(x) { sample(x) })

0

Mẫu ngẫu nhiên và hoán vị trong khung dữ liệu Nếu nó ở dạng ma trận, hãy chuyển đổi thành dữ liệu. Khung sử dụng hàm mẫu từ gói cơ sở indexes = sample (1: nrow (df1), size = 1 * nrow (df1)) Mẫu ngẫu nhiên và hoán vị

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.