2013-06-18 33 views
25

Chức năng Rexpand.grid trả về tất cả các kết hợp có thể có giữa các yếu tố của tham số được cung cấp. ví dụ.Phiên bản không cần thiết của expand.grid

> expand.grid(c("aa", "ab", "cc"), c("aa", "ab", "cc")) 
    Var1 Var2 
1 aa aa 
2 ab aa 
3 cc aa 
4 aa ab 
5 ab ab 
6 cc ab 
7 aa cc 
8 ab cc 
9 cc cc 

Bạn có biết một cách hiệu quả để có được trực tiếp (như vậy mà không bất cứ so sánh liên tiếp sau khi expand.grid) chỉ sự kết hợp 'độc đáo' giữa các vectơ cung cấp? Sản lượng sẽ

Var1 Var2 
1 aa aa 
2 ab aa 
3 cc aa 
5 ab ab 
6 cc ab 
9 cc cc 

EDIT sự kết hợp của mỗi phần tử với chính nó có thể sẽ được loại bỏ từ các câu trả lời. Tôi không thực sự cần nó trong chương trình của tôi mặc dù (toán học) aa aa sẽ là một (thường xuyên) kết hợp độc đáo giữa một yếu tố của Var1 và một trong số var2.

Giải pháp này cần để sản xuất cặp của các yếu tố từ cả hai vectơ (có nghĩa là mật từ mỗi vectơ đầu vào - vì vậy mà nó có thể được áp dụng cho hơn 2 đầu vào)

+0

Không phải là [this] (https://stackoverflow.com/questions/12245213/how-to-generate-all-possible-combinations-of-vectors-without-caring-for-order) chỉ là cùng một câu hỏi ? – 5th

+0

Có thể trùng lặp của [Làm thế nào để tạo ra tất cả các kết hợp có thể có của vectơ mà không quan tâm đến trật tự?] (Https://stackoverflow.com/questions/12245213/how-to-generate-all-possible-combinations-of-vectors-without- chăm sóc theo đơn đặt hàng) – 5th

+0

Tôi không nghĩ vậy. Điều đó hỏi về các phần tử từ một vectơ đơn lẻ. các câu trả lời được chấp nhận cũng cung cấp một cách để tạo ra các kết hợp từ các yếu tố của nhiều đầu vào (2 hoặc nhiều hơn) – Michele

Trả lời

23

Làm thế nào về việc sử dụng outer? Nhưng chức năng đặc biệt này nối chúng thành một chuỗi ký tự.

outer(c("aa", "ab", "cc"), c("aa", "ab", "cc") , "paste") 
#  [,1] [,2] [,3] 
#[1,] "aa aa" "aa ab" "aa cc" 
#[2,] "ab aa" "ab ab" "ab cc" 
#[3,] "cc aa" "cc ab" "cc cc" 

Bạn cũng có thể sử dụng combn trên các yếu tố độc đáo của hai vectơ nếu bạn không muốn các yếu tố lặp lại (ví dụ aa aa)

vals <- c(c("aa", "ab", "cc"), c("aa", "ab", "cc")) 
vals <- unique(vals) 
combn(vals , 2) 
#  [,1] [,2] [,3] 
#[1,] "aa" "aa" "ab" 
#[2,] "ab" "cc" "cc" 
+0

oh không, cảm ơn. Tôi cần chúng riêng biệt để chuyển sang chức năng khác. trước đó là hoàn hảo! Tôi thực sự nhận ra rằng tôi không cần 'aa aa', 'bb bb' và' cc cc'. vì vậy nếu bạn chỉnh sửa lại và tôi sẽ chấp nhận nó :-) – Michele

10

Nếu hai vectơ đều giống nhau, có các combinations chức năng trong gói gtools:

library(gtools) 
combinations(n = 3, r = 2, v = c("aa", "ab", "cc"), repeats.allowed = TRUE) 

#  [,1] [,2] 
# [1,] "aa" "aa" 
# [2,] "aa" "ab" 
# [3,] "aa" "cc" 
# [4,] "ab" "ab" 
# [5,] "ab" "cc" 
# [6,] "cc" "cc" 

Và không "aa" "aa" vv

combinations(n = 3, r = 2, v = c("aa", "ab", "cc"), repeats.allowed = FALSE) 
+0

+1 Tôi không biết về gtools, cảm ơn! –

+0

Tôi lưu ý rằng repeats.allowed cũng loại bỏ các cặp tự như ("aa", "aa"), không thực sự lặp lại. Có một cách giữa bị thiếu với hàm này. – Deleet

9

Trong cơ sở R, bạn có thể sử dụng này:

expand.grid.unique <- function(x, y, include.equals=FALSE) 
{ 
    x <- unique(x) 

    y <- unique(y) 

    g <- function(i) 
    { 
     z <- setdiff(y, x[seq_len(i-include.equals)]) 

     if(length(z)) cbind(x[i], z, deparse.level=0) 
    } 

    do.call(rbind, lapply(seq_along(x), g)) 
} 

Kết quả:

> x <- c("aa", "ab", "cc") 
> y <- c("aa", "ab", "cc") 

> expand.grid.unique(x, y) 
    [,1] [,2] 
[1,] "aa" "ab" 
[2,] "aa" "cc" 
[3,] "ab" "cc" 

> expand.grid.unique(x, y, include.equals=TRUE) 
    [,1] [,2] 
[1,] "aa" "aa" 
[2,] "aa" "ab" 
[3,] "aa" "cc" 
[4,] "ab" "ab" 
[5,] "ab" "cc" 
[6,] "cc" "cc" 
+0

chức năng tuyệt vời, cảm ơn bạn rất nhiều. – Stu

+0

Tôi lưu ý rằng nó thiếu một cách để có được các mối quan hệ tự bao gồm, nhưng không phải là những cách trùng lặp. Ví dụ: "aa", "aa") không phải là bản sao cho nó chỉ xuất hiện. Trong một số trường hợp, người ta cũng muốn các mối quan hệ tự, nhưng không phải là các bản sao. – Deleet

3

Hãy thử:

factors <- c("a", "b", "c") 

all.combos <- t(combn(factors,2)) 

    [,1] [,2] 
[1,] "a" "b" 
[2,] "a" "c" 
[3,] "b" "c" 

này sẽ không bao gồm bản sao của mỗi yếu tố (ví dụ "a" "a"), nhưng bạn có thể thêm chúng một cách dễ dàng nếu cần.

dup.combos <- cbind(factors,factors) 

    factors factors 
[1,] "a"  "a"  
[2,] "b"  "b"  
[3,] "c"  "c" 

all.combos <- rbind(all.combos,dup.combos) 

    factors factors 
[1,] "a"  "b"  
[2,] "a"  "c"  
[3,] "b"  "c"  
[4,] "a"  "a"  
[5,] "b"  "b"  
[6,] "c"  "c" 
4

Câu trả lời trước không có cách nào để có được kết quả cụ thể, giữ nguyên các cặp nhưng loại bỏ các đơn đặt hàng khác nhau. Gói gtools có hai chức năng cho các mục đích này, combinationspermutations. According to this website:

  • Khi đơn đặt hàng không quan trọng, đó là Kết hợp.
  • Khi thứ tự quan trọng, đó là một phép hoán vị.

Trong cả hai trường hợp, chúng tôi có quyết định thực hiện việc lặp lại được phép hay không, và tương ứng, cả hai hàm đều có đối số repeats.allowed, cho 4 kết hợp (siêu ngon!). Đó là giá trị đi qua mỗi trong số này. Tôi đã đơn giản hóa vector thành các chữ cái đơn để dễ hiểu.

hoán vị với sự lặp lại

Các tùy chọn mở rộng nhất là cho phép cả hai tự quan hệ và cách khác nhau đã ra lệnh lựa chọn:

> permutations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c")) 
     [,1] [,2] 
[1,] "a" "a" 
[2,] "a" "b" 
[3,] "a" "c" 
[4,] "b" "a" 
[5,] "b" "b" 
[6,] "b" "c" 
[7,] "c" "a" 
[8,] "c" "b" 
[9,] "c" "c" 

mà cho chúng ta 9 lựa chọn. Bạn có thể tìm thấy giá trị này từ công thức đơn giản n^r tức là 3^2=9. Đây là the Cartesian product/join cho người dùng quen thuộc với SQL.

Có hai cách để giới hạn điều này: 1) loại bỏ mối quan hệ tự (không cho phép lặp lại) hoặc 2) xóa các tùy chọn được sắp xếp khác nhau (tức là kết hợp).

kết hợp với lần lặp lại

Nếu chúng ta muốn loại bỏ cách khác nhau đã ra lệnh lựa chọn, chúng tôi sử dụng:

> combinations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c")) 
    [,1] [,2] 
[1,] "a" "a" 
[2,] "a" "b" 
[3,] "a" "c" 
[4,] "b" "b" 
[5,] "b" "c" 
[6,] "c" "c" 

mà cho chúng ta 6 lựa chọn. Công thức cho giá trị này là (r+n-1)!/(r!*(n-1)!) tức là (2+3-1)!/(2!*(3-1)!)=4!/(2*2!)=24/4=6.

hoán vị không lặp lại

Nếu thay vào đó chúng tôi muốn để không cho phép lặp lại, chúng tôi sử dụng:

> permutations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c")) 
    [,1] [,2] 
[1,] "a" "b" 
[2,] "a" "c" 
[3,] "b" "a" 
[4,] "b" "c" 
[5,] "c" "a" 
[6,] "c" "b" 

đó cũng cho chúng ta 6 lựa chọn, nhưng những người khác nhau! Số lượng tùy chọn giống như ở trên nhưng đó là sự trùng hợp ngẫu nhiên. Giá trị có thể được tìm thấy từ công thức n!/(n-r)! tức là (3*2*1)/(3-2)!=6/1!=6.

kết hợp mà không lặp lại

Các hạn chế nhất là khi chúng ta muốn không phải tự quan hệ/lần lặp lại hoặc cách khác nhau đã ra lệnh tùy chọn, trong trường hợp này chúng tôi sử dụng:

> combinations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c")) 
    [,1] [,2] 
[1,] "a" "b" 
[2,] "a" "c" 
[3,] "b" "c" 

mà cho chúng ta chỉ có 3 lựa chọn. Số lượng tùy chọn có thể được tính từ công thức khá phức tạp n!/(r!(n-r)!) tức là 3*2*1/(2*1*(3-2)!)=6/(2*1!)=6/2=3.