2013-06-18 3 views
25

Функция Rexpand.grid возвращает всю возможную комбинацию между элементами поставляемых параметров. напримерНепрозрачная версия 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 

вы знаете эффективный способ получить непосредственно (так без какого-либо сравнения строк после expand.grid) только «уникальные» комбинации между прилагаемыми векторами ли? Выход будет

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

РЕДАКТИРОВАТЬ сочетание каждого элемента с самим собой может быть в конечном итоге отбрасываются от ответа. Я действительно не нуждаюсь в нем в своей программе, хотя (математически) aa aa будет одной (обычной) уникальной комбинацией между одним элементом Var1 и еще одним из var2.

Решение должно производить пар элементов из обоих векторов (то есть по одному от каждого из входных векторов - так, чтобы он мог быть применен к более чем 2 входов)

+0

Это не [это] (https://stackoverflow.com/questions/12245213/how-to-generate-all-possible-combinations-of-vectors-without-caring-for-order) только тот же вопрос ? – 5th

+0

Возможный дубликат [Как сгенерировать все возможные комбинации векторов без заботы о заказе?] (Https://stackoverflow.com/questions/12245213/how-to-generate-all-possible-combinations-of-vectors-without- забота за заказ) – 5th

+0

Я так не думаю. Это спрашивает об элементах из одного вектора. принятые ответы также обеспечивают способ создания комбинаций из элементов с несколькими входами (2 или более) – Michele

ответ

23

Как об использовании outer? Но эта конкретная функция объединяет их в одну строку символов.

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" 

Вы также можете использовать combn на уникальных элементов двух векторов, если вы не хотите, повторяющиеся элементы (например 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

нет, спасибо. Мне нужно, чтобы они были разными, чтобы перейти к другой функции. предыдущий был идеален! Я действительно понял, что мне не нужны 'aa aa',' bb bb' и 'cc cc'. так что если вы снова отредактируете назад, и я приму это :-) – Michele

10

Если два вектора одинаковы, есть combinations функция в 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" 

И без "aa" "aa" и т.д.

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

+1 Я не знал о gtools, спасибо! –

+0

Я отмечаю, что повторы. Разрешенные также удаляют самопар, таких как («aa», «aa»), которые на самом деле не повторяются. С этой функцией отсутствует средний путь. – Deleet

9

В базовой R, вы можете использовать это:

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

Результаты:

> 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

большой функция, большое спасибо. – Stu

+0

Я отмечаю, что у него отсутствует способ включения в себя самостоятельных отношений, но не дубликатов. Например («aa», «aa») не является дубликатом, поскольку он появляется только. В некоторых случаях тоже нужны отношения, но не дубликаты. – Deleet

3

TRY:

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

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

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

Это не будет включать дубликаты каждого фактора (например «a», «a»), но вы можете добавить их легко, если это необходимо.

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

В предыдущих ответах отсутствовал способ получить конкретный результат, а именно сохранить собственные пары, но удалить их с разными порядками. Пакет gtools содержит две функции для этих целей, combinations и permutations. According to this website:

  • Когда заказ не имеет значения, это комбинация.
  • Когда заказ имеет значение, это перестановка.

В обоих случаях мы имеем решение сделать ли повторы разрешены или нет, и, соответственно, обе функции имеют repeats.allowed аргумент, получают 4 комбинации (очаровательно мета!). Стоит пережить каждый из них. Я упростил вектор для одиночных букв для удобства понимания.

Перестановка с повторением

Самым обширным вариантом, чтобы позволить самодисциплину отношения и по-разному упорядоченным варианты:

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

, который дает нам 9 вариантов. Это значение можно найти по простой формуле n^r, то есть 3^2=9. Это the Cartesian product/join для пользователей, знакомых с SQL.

Есть два способа ограничить это: 1) удалить самосогласования (запретить повторения) или 2) удалить по-разному упорядоченные параметры (т. Е. Комбинации).

Сочетания с повторениями

Если мы хотим, чтобы удалить по-разному упорядоченный варианты, мы используем:

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

, который дает нам 6 вариантов. Формула для этого значения равна (r+n-1)!/(r!*(n-1)!), то есть (2+3-1)!/(2!*(3-1)!)=4!/(2*2!)=24/4=6.

Перестановка без повторений

Если вместо этого мы хотим запретить повторы, мы используем:

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

которая также дает нам 6 вариантов, но разные из них! Количество опций такое же, как и выше, но это совпадение. Значение можно найти по формуле n!/(n-r)!, то есть (3*2*1)/(3-2)!=6/1!=6.

комбинаций без повторений

Наиболее ограничение, когда мы хотим ни автопортреты отношения/повторы или по-разному упорядоченные варианты, в этом случае мы используем:

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

, который дает нам только три варианта. Количество опций можно рассчитать по довольно сложной формуле n!/(r!(n-r)!), то есть 3*2*1/(2*1*(3-2)!)=6/(2*1!)=6/2=3.

Смежные вопросы