Подтвердить что ты не робот

Не избыточная версия expand.grid

Функция R 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

EDIT комбинация каждого элемента с собой может быть в конечном итоге отброшена из ответа. Я действительно не нуждаюсь в ней в своей программе, хотя (математически) aa aa будет одной (регулярной) уникальной комбинацией между одним элементом Var1 и другим из var2.

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

4b9b3361

Ответ 1

Как насчет использования 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"

Ответ 2

Если два вектора совпадают, в < <21 > есть функция combinations:

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)

Ответ 3

В базе 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"

Ответ 4

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

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

В обоих случаях мы принимаем решение о допустимости повторений или нет, и, соответственно, обе функции имеют аргумент 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 i.e 3^2=9. Это декартово произведение /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)!) i.e. (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)! i.e. (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" 

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

Ответ 5

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"