2017-01-17 6 views
0

У меня есть симметричная матрица и одна конкретная группа, которая применяется как к строкам, так и столбцам. Я пытаюсь суммировать только те строки и столбцы на основе этой конкретной группировки.R - сумма матричных строк и столбцов на основе группировок

Например, у меня есть 4 x 4 матрицы. У меня также есть определенная группа, такая как 1,1,2,2. То есть строки и столбцы 1 и 2 относятся к группе 1, тогда как строки и столбцы 3 и 4 относятся к группе 2. Я хотел бы применить функции rowSums или rowsum, оставаясь верными для групповых ограничений:

Моя матрица:

 [,1] [,2] [,3] [,4] 
[1,]  0 1 0 0 
[2,]  1 0 1 0 
[3,]  0 1 0 3 
[4,]  3 0 0 0 

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

 [,1] [,2] [,3] [,4] 
[1,]  0 1 NA NA 
[2,]  1 0 NA NA 
[3,]  NA NA 0 3 
[4,]  NA NA 0 0 

Применение rowSums к исходной матрице даст:

[1] 1 2 4 3 

Кроме того, применение rowsum, что позволяет прохождение группы, относится только группировка к строкам и по-прежнему суммирует те столбцы, которые не являются частью группы:

 [,1] [,2] [,3] [,4] 
1  1 1 1 0 
2  3 1 0 3 

Причина, по которой это проблема заключается в том, что я пытаюсь найти минимальное значение в каждой группе. Поскольку вышеупомянутое включает столбцы, которые не являются частью группы, результат будет неправильным. Я мог бы утомительно петлю через группировки и применить rowSums для получения суммы в каждую группу, а затем найти минимум:

rowSums(mat[c(1,2),c(1,2)]) 
[1] 1 1 <- minimum is 1 
rowSums(mat[c(3,4),c(3,4)]) 
[1] 3 0 <- minimum is 0 

Тем не менее, у меня есть большая матрица, и этот метод не является практичным. Я почти уверен, что есть более эффективный и простой способ сделать это, но я не могу найти его. В идеале я хотел бы выход быть что-то вроде:

1 1 2 2 <- grouping 
1 1 3 0 

или даже

 [,1] [,2] [,3] [,4] 
1  1 1 Inf Inf 
2  Inf Inf 3 0 

Любые предложения будут высоко оценены.

Спасибо.

Edit:

Я регулируя мой вопрос к следующему. Учитывая мой исходная матрица:

 [,1] [,2] [,3] [,4] 
[1,]  0 1 0 0 
[2,]  1 0 1 0 
[3,]  0 1 0 3 
[4,]  3 0 0 0 

и специфическая группировка:

groups<-c(1,1,2,2) 

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

groups<-c(1,1,2,2) 
for(i in 1:length(groups)) 
{ 
    mat[i,which(groups[i]!=groups)]<-NA 
} 

mat 

    [,1] [,2] [,3] [,4] 
[1,] 0 1 NA NA 
[2,] 1 0 NA NA 
[3,] NA NA 0 3 
[4,] NA NA 0 0 

Как я могу добиться этого без использование неэффективного цикла?

+0

Как вы получите '3 'в' 1 1 3 0', если вы берете минимальное значение – akrun

+0

Я считаю, что ему нужен макс макс [1: 2,1: 2] и матов [3: 4,3: 4]. Группировка c (1,1,2,2) применяется к обоим строкам и столбцам. – Haboryme

+0

На этом этапе я просто хотел отобразить суммы строк для каждой группы (перед поиском минимального значения для каждой группы). – hsn

ответ

1

Возможно, это помогает

sapply(split(mat, kronecker(matrix(1:4, nrow=2, byrow=TRUE), 
     matrix(1, 2, 2))), function(x) rowSums(matrix(x, ncol=2))) 
#  1 2 3 4 
#[1,] 1 0 1 3 
#[2,] 1 1 3 0 
Объяснение
kronecker(matrix(1:4, nrow=2, byrow=TRUE), matrix(1, 2, 2)) 
#  [,1] [,2] [,3] [,4] 
#[1,] 1 1 2 2 
#[2,] 1 1 2 2 
#[3,] 3 3 4 4 
#[4,] 3 3 4 4 

kronecker произведение двух массивов возвращает индекс группировки, как показано выше. Используйте это, чтобы split матрицу

split(mat, kronecker(matrix(1:4, nrow=2, byrow=TRUE), 
    matrix(1, 2, 2))) 
#$`1` 
#[1] 0 1 1 0 

#$`2` 
#[1] 0 1 0 0 

#$`3` 
#[1] 0 3 1 0 

#$`4` 
#[1] 0 0 3 0 

Он возвращает list из vector s

Преобразование vector в matrix и получить rowSums обернув над list с sapply

+0

Спасибо. Ваш ответ заставил меня задуматься о том, как использовать sapply на моей матрице. Я отредактировал мой вопрос выше, чтобы перенаправить желаемый результат. Взгляни, пожалуйста. Благодаря! – hsn