Умный способ изменить порядок записи этой структурированной матрицы в R? - PullRequest
2 голосов
/ 20 декабря 2011

Рассмотрим следующий фрагмент:

>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

Как бы вы поступили?

Ответы [ 4 ]

6 голосов
/ 20 декабря 2011

НИКОГДА не вызывайте переменную 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))
}

Внутренняя функция comp заменит измененный элемент при необходимости. Основная функция использует 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

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

3 голосов
/ 20 декабря 2011

Используйте правило KISS: для этого примера я просто использовал 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 голосов
/ 20 декабря 2011

В основном найдите индекс столбца, который идентифицирует «новый» элемент при сравнении с приведенной выше строкой, и поменяйте его местами с 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
0 голосов
/ 20 декабря 2011

Может помочь:

 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-я строка -

T[5, ] = 1 6 4 5 3 

а не

T[5, ] = 1 6 5 4 3 

Почему 5 и 4 инвертированы в их порядке?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...