Добавление диагоналей матрицы с помощью R

Я хотел бы сложить диагонали верхней части матрицы, начиная с середины, с приращением в столбце до (1,n), где n будет последним столбцом, и сохранить каждую сумму каждой диагонали. Мой код добавляет только среднюю диагональ, как я могу перебрать матрицу, чтобы получить сумму диагоналей

A <- matrix(c(2, 4, 3, 1,
             5, 7, 1, 2,
             3, 2, 3, 4, 
             1, 5, 6, 0), # the data elements 
    nrow = 4, # number of rows 
    ncol = 4, # number of columns 
    byrow = TRUE) # fill matrix by rows

sum <- 0
print(A)
for (a in 1){
  for (b in 1:ncol){
    if (a<-b){
      sum = sum + A[a,b]
      print (sum) 
    }
  }
}

Вот мой результат

> print(A)
     [,1] [,2] [,3] [,4]
[1,]    2    4    3    1
[2,]    5    7    1    2
[3,]    3    2    3    4
[4,]    1    5    6    0

for (a in 1){
  for (b in 1:ncol){ 
    if (a<-b){
      sum = sum + A[a,b]
      tail(sum, n=1)
    }
  }
}


12

person shegzter    schedule 22.03.2018    source источник
comment
ты имеешь в виду if (a==b) ??? иначе я не понимаю, как это будет работать...   -  person Ben Bolker    schedule 22.03.2018
comment
Я не могу сказать, каков ваш желаемый результат. Это c(1,8,13,12,9,5,1), то есть суммы недиагональных элементов?   -  person Ben Bolker    schedule 22.03.2018


Ответы (2)


Вам нужно diag, чтобы извлечь все элементы главной диагонали, и sum, чтобы получить их сумму.

sum(diag(A))

Я не уверен в том, что вы просите, но если вы также хотите извлечь верхнюю треугольную матрицу, вы можете использовать A[upper.tri(A)], который исключает основные диагональные элементы, вы также можете установить diag=TRUE, чтобы включить их A[upper.tri(A, diag = TRUE)]

@shegzter, основываясь на вашем комментарии, вы можете использовать col и row в сочетании с логическим сравнением ==, чтобы получить нужные вам числа.

> A[row(A)==col(A)] # this gives the same out put as `diag(A)`
[1] 2 7 3 0
> A[row(A)+1==col(A)]
[1] 4 1 4
> A[row(A)+2==col(A)]
[1] 3 2
> A[row(A)+3==col(A)]
[1] 1

Если вам нужна сумма каждого из них, используйте sum над этими элементами:

> sum(A[row(A)==col(A)])
[1] 12
> sum(A[row(A)+1==col(A)])
[1] 9
> sum(A[row(A)+2==col(A)])
[1] 5
> sum(A[row(A)+3==col(A)])
[1] 1

Если ваша цель получить следующую сумму 12+9+5+1, то вы можете сделать это все сразу, используя upper.tri и sum

> sum(A[upper.tri(A, diag = TRUE)])
[1] 27

Или без диагональных элементов:

> sum(A[upper.tri(A)])
[1] 15
person Jilber Urbina    schedule 22.03.2018
comment
Я хочу иметь возможность получить 2 + 7+ 3 + 0 = 12 (которые у меня уже есть) 4+ 1+ 4 = 9 3+2 = 5 1 - person shegzter; 22.03.2018

Следующее возвращает сумму для каждой диагонали:

sapply(split(A, col(A) - row(A)), sum)
# -3 -2 -1  0  1  2  3 
#  1  8 13 12  9  5  1

Следовательно, чтобы получить только верхние, вы можете использовать

tail(sapply(split(A, col(A) - row(A)), sum), ncol(A))
#  0  1  2  3 
# 12  9  5  1 

Недостаток использования tail заключается в том, что мы также вычисляем меньшие диагональные суммы. Следовательно, чтобы сэкономить время, когда A велико, вы можете использовать

sapply(split(A[upper.tri(A, diag = TRUE)], (col(A) - row(A))[upper.tri(A, diag = TRUE)]), sum)
#  0  1  2  3 
# 12  9  5  1 
person Julius Vainora    schedule 22.03.2018