2016-05-13 5 views
1

Эта небольшая проблема является узким местом большого кода, который должен повторяться по меньшей мере тысячи раз, поэтому основной проблемой здесь является скорость.Ускоренная комбинация с матрицей ID R

У меня есть вектор чисел, например:

v <- c(1,3,5) 

Я хочу знать все комбинации, я могу сделать с этим подмножеством. И поставил их в матрицу из 0 и 1-х, например:

col1 col2 col3 col4 col5 col6 col7 
1 1 0 0 1 1 0 1 
3 0 1 0 1 0 1 1 
5 0 0 1 0 1 1 1 

На самом деле я использую функцию combn (я думаю, что это самый быстрый способ сделать это чистый, правда?)

matrix <- lapply(seq(length(v)),function(i){ 
       submatrix <- combn(x = 1:length(v), m=i) 

#code follows after a brief explanation 

Я хотел бы получить три матрицы, как:

1 2 3 

1 1 2 
2 3 3 

1 
2 
3 

Таким образом, чтобы получить матрицу 1 и 0, я заполнить его с дублером. (Вот, где, вероятно, я мог бы получить некоторую скорость)

list_matrix <- lapply(seq(length(v)),function(i){ 
    submatrix <- combn(x = 1:length(v), m=i) 
    1matrix <- matrix(data = 0, nrow = length(v), ncol = dim(submatrix)[2]) 

    for(k in seq(dim(submatrix)[2])) 
     for(j in seq(dim(submatrix)[1])) 
      1matrix[submatrix[j,k],k] <- 1 

    return(1matrix) })  

То, что я показал, является самой медленной частью кода. Для этого примера выполняется aprox 0,012 с. Следующий шаг прост.

То, что я получил три матрицы:

col1 col2 col3 
1 1 0 0 
3 0 1 0 
5 0 0 1 

    col1 col2 col3 
1 1 1 0 
3 1 0 1 
5 0 1 1 

    col1 
1 1 
3 1 
5 1 

Теперь процесс довольно прост и быстр.

final_matrix <- list_matrix[[1]] 

for(i in seq(2,length(list_matrix)) 
    final_matrix <- cbind(final_matrix, list_matrix[[i]] 

И что это делает, вставляем столбцы, чтобы получить. Требуется 0,0033 с:

col1 col2 col3 col4 col5 col6 col7 
1 1 0 0 1 1 0 1 
3 0 1 0 1 0 1 1 
5 0 0 1 0 1 1 1 

Мне нужно ускорить этот процесс. Я думаю, что двойное или замедленное замедляет это. Если кто-то сможет опубликовать некоторую помощь, я буду признателен.

спасибо.

+2

Похоже, что вы можете использовать '? Expand.grid', если это соответствует вашей общей проблеме; 't (expand.grid (rep_len (list (0: 1), length (v)))) [, -1]' –

+0

Я думаю, что это может сработать. Спасибо. –

ответ

1

Вы можете использовать tabulate, чтобы упростить код:

L <- sapply(1:length(v), function(i) combn(length(v),i,FUN=tabulate,nbins=length(v))) 
do.call(cbind,L) 
#  [,1] [,2] [,3] [,4] [,5] [,6] [,7] 
#[1,] 1 0 0 1 1 0 1 
#[2,] 0 1 0 1 0 1 1 
#[3,] 0 0 1 0 1 1 1 

Обратите внимание, что combn само по себе медленно, так что вы можете изучить его более быстрые аналоги, смотри, например, Faster version of combn

+0

Я проверю это. Спасибо. –