2011-12-20 3 views
2

Рассмотрим следующий фрагмент кода:Умный способ переупорядочить запись этой структурированной матрицы в R?

>k<-5 
>T<-t(combn(k+1,k)) 
>T 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 2 3 4 5 
[2,] 1 2 3 4 6 
[3,] 1 2 3 5 6 
[4,] 1 2 4 5 6 
[5,] 1 3 4 5 6 
[6,] 2 3 4 5 6 

за исключением первой строки, каждая строка T[i,] из T имеет k элементы, k-1 из , которые являются общими с T[i-1,].

Я хочу, чтобы изменить порядок записи в данной линии T[i,], i>1 такой, что «новый» вход в каждой строке помещается в последней колонке.

т.е. я хочу повторно заказать столик выглядеть следующим образом:

 [,1] [,2] [,3] [,4] [,5] 
[1,] 1 2 3 4 5 
[2,] 1 2 3 4 6 
[3,] 1 2 3 6 5 
[4,] 1 2 6 5 4 
[5,] 1 6 4 5 3 
[6,] 6 3 4 5 2 

Как бы вы об этом?

+0

ОК, как мы можем перенести вопрос (без перекрестной публикации)? – user189035

+0

ok Seb:> помечено для внимания modo. Посмотрим. Благодарю. – user189035

+0

Также рассмотрите возможность изменения названия вашего вопроса на что-то более описательное. –

ответ

6

НИКОГДА НЕ ЗНАЮ переменную T. Да, это действительное имя. Да, весь код должен использовать TRUE для логического значения, но есть достаточно фрагментов кода, где они фактически используют T для TRUE. Ты сломаешь их.

Вы можете использовать следующую функцию:

new.order <- function(x){ 
    comp <- function(a,b){ 
     id <- which(match(a,b,0L)==0) 
     if(id!=nc){ 
      b[nc] <- b[id] 
      b[id] <- a[nc] 
     } 
     b 
    } 
    nr <- nrow(x) 
    nc <- ncol(x) 
    xlist <- lapply(seq_len(nr),function(i) x[i,]) 
    out <- mapply(comp,xlist[-nr],xlist[-1],SIMPLIFY=FALSE) 
    do.call(rbind,c(xlist[1],out)) 
} 

Внутренняя функция комп, если необходимо будет заменить измененный элемент. Основная функция использует lapply, чтобы сделать вашу матрицу списком, а затем mapply, чтобы выполнить сопоставление по всем строкам. Последнее (но не менее важное), вы соединяете все вместе.

Это дает

> k<-5 

> myT<-t(combn(k+1,k)) 

> myT 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 2 3 4 5 
[2,] 1 2 3 4 6 
[3,] 1 2 3 5 6 
[4,] 1 2 4 5 6 
[5,] 1 3 4 5 6 
[6,] 2 3 4 5 6 

> new.order(myT) 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 2 3 4 5 
[2,] 1 2 3 4 6 
[3,] 1 2 3 6 5 
[4,] 1 2 6 5 4 
[5,] 1 6 4 5 3 
[6,] 6 3 4 5 2 

который, кажется, желаемого результата.

+0

Спасибо за совет. – user189035

+1

@ user189035 Я пропустил одну строку на выходе, исправил ее сейчас –

+0

Я думаю, что вы можете немного ускорить свой код, если вы замените функцию 'comp' чем-то вроде: ' r2 <-r2 [c (который (соответствует (r1, r2,0)! = 0), которые (match (r1, r2,0) == 0))] ' –

0

мая эта помощь:

for(i in 1:ncol(T)) T[i+1, (nrow(T)-i):ncol(T)] = nrow(T):(nrow(T)-i+1)

T= 
     [,1] [,2] [,3] [,4] [,5] 
[1,] 1 2 3 4 5 
[2,] 1 2 3 4 6 
[3,] 1 2 3 6 5 
[4,] 1 2 6 5 4 
[5,] 1 6 5 4 3 
[6,] 6 5 4 3 2 

Однако, я не понимаю логику второго выхода Т. Почему пятой линии

T[5, ] = 1 6 4 5 3

и не

T[5, ] = 1 6 5 4 3

Почему 5 и 4 инвертируют свои или дер?

+0

относительно вашего вопроса: «новый» элемент в 5-й строке равен 3 (3 не отображается в 4-й строке). Поэтому я хочу, чтобы последний столбец 5-й строки переупорядоченной матрицы Т 'равнялся 3. Остальные записи должны быть оставлены так же, как они есть в Т (кроме обитателя последнего столбца 5-й строки, который должен быть перемещен где было 3). Отвечает ли это на ваш вопрос? – user189035

0

В принципе найти индекс столбца, который идентифицирует «новый» элемент при сравнении со строкой выше, и поменять его с 5.

for (row.idx in 2:6){ T[row.idx, c(which(!T[row.idx,] %in% T[row.idx-1,]), 5)] <- 
          T[row.idx, c(5, which(!T[row.idx,] %in% T[row.idx-1,]))] } 
T 
rm(T) # not a good idea to have that lying around your workspace 
     # ... even if you don't use T for TRUE 
# 
#  [,1] [,2] [,3] [,4] [,5] 
[1,] 1 2 3 4 5 
[2,] 1 2 3 4 6 
[3,] 1 2 3 6 5 
[4,] 1 2 6 5 4 
[5,] 1 6 4 5 3 
[6,] 6 3 4 5 2 
3

Использование правила ПОЦЕЛУЙ: Для этого примера, у меня просто использовали r1, r2, r3 вместо T [i,], «старый» T [i + 1,], «новый» T [i + 1,].

Rgames: r1<-c(1,2,6,4,3) 

Rgames: r2<-c(1,2,5,4,3) 

Rgames: r3<-c(intersect(r1,r2),setdiff(r2,r1)) 
Rgames: r3 
[1] 1 2 4 3 5 
+0

+1 для упоминания intersect и setdiff. Как правило, я стараюсь вырезать двойной код по соображениям производительности. Поэтому мое использование матча. –

+0

+1 такой же причина. – user189035

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