Issue
I have a data frame called "relations":
library(tidyverse)
library(igraph)
set.seed(123)
n=10
data = tibble(d = paste(1:n))
relations = tibble(
from = sample(data$d),
to = lead(from, default=from[1]),
)
relations = data.frame(relations)
The "relations" data frame looks like this:
from to
1 3 10
2 10 2
3 2 8
4 8 6
5 6 9
6 9 1
7 1 7
8 7 5
9 5 4
10 4 3
I then have a matrix called "m" (the dimensions of this matrix correspond to the "relations" data frame):
m<matrix(rnorm(100) , nrow = 10)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1.66794194 0.6407060 0.07796085 0.7399475 0.6879168 0.3724388 0.48378063 0.3104807 0.08473729 1.2512714
[2,] 0.38022652 0.8497043 0.96185663 1.9091036 2.1001089 0.9769734 0.51686204 0.4365235 0.75405379 0.6111659
[3,] 0.91899661 1.0241288 0.07130809 1.4438932 1.2870305 0.3745809 0.36896453 0.4583653 0.49929202 1.1854801
[4,] 0.57534696 0.1176466 1.44455086 0.7017843 0.7877388 1.0527115 0.21538051 1.0633261 0.21444531 2.1988103
[5,] 0.60796432 0.9474746 0.45150405 0.2621975 0.7690422 1.0491770 0.06529303 1.2631852 0.32468591 1.3124130
[6,] 1.61788271 0.4905574 0.04123292 1.5721442 0.3322026 1.2601552 0.03406725 0.3496504 0.09458353 0.2651451
[7,] 0.05556197 0.2560922 0.42249683 1.5146677 1.0083766 3.2410399 2.12845190 0.8655129 0.89536336 0.5431941
[8,] 0.51940720 1.8438620 2.05324722 1.6015362 0.1194526 0.4168576 0.74133610 0.2362796 1.31080153 0.4143399
[9,] 0.30115336 0.6519499 1.13133721 0.5309065 0.2803953 0.2982276 1.09599627 0.1971759 1.99721338 0.4762469
[10,] 0.10567619 0.2353866 1.46064007 1.4617556 0.5629895 0.6365697 0.03778840 1.1099203 0.60070882 0.7886028
I would like to write a function that :

selects the element in the matrix "m" corresponding to the "(from,to) numbers" for each row in the "relations" data frame

and then sums all these elements together
In my case, this would look something like this:
sums = m[3,10] + m[10,2] + m[2,8] + m[8,6] + m[6,9] + m[9,1] + m[1,7] + m[7,5] + m[5,4] + m[4,3]
sums
[1] 0.8444946
I thought that perhaps I could "reference" the correct elements in the matrix using the following "trick":
sums = m[relations[1,1], relations[1,2]] + m[relations[2,1], relations[2,2]] + m[relations[3,1], relations[3,2]] + m[relations[4,1], relations[4,2]] + m[relations[5,1], relations[5,2]] + m[relations[6,1], relations[6,2]] + m[relations[7,1], relations[7,2]] + m[relations[8,1], relations[8,2]] + m[relations[9,1], relations[9,2]] + m[relations[10,1], relations[10,2]]
Error in m[relations[1, 1], relations[1, 2]] : subscript out of bounds
I then tried this:
sums = m[as.numeric(relations[1,1]), as.numeric(relations[1,2])] +
m[as.numeric(relations[2,1]), as.numeric(relations[2,2])]
+ m[as.numeric(relations[3,1]), as.numeric(relations[3,2])]
+ m[as.numeric(relations[4,1]), as.numeric(relations[4,2])]
+ m[as.numeric(relations[5,1]), as.numeric(relations[5,2])] +
m[as.numeric(relations[6,1]), as.numeric(relations[6,2])] +
m[as.numeric(relations[7,1]), as.numeric(relations[7,2])] +
m[as.numeric(relations[8,1]), as.numeric(relations[8,2])] +
m[as.numeric(relations[9,1]), as.numeric(relations[9,2])] +
m[as.numeric(relations[10,1]), as.numeric(relations[10,2])]
X9
0.08593303
Although I think of made a mistake, because the
0.8444946 <> 0.08593303
How can I write a function that that automatically performs the following operation for any "relations" and "m"?
sums = m[3,10] + m[10,2] + m[2,8] + m[8,6] + m[6,9] + m[9,1] + m[1,7] + m[7,5] + m[5,4] + m[4,3]
Thank you!
Solution
You can index a matrix m
using [
and another matrix with columns corresponding to the rows and columns of m
, just like your relations
object. So all we need to do is covert relations
to matrix
, use it to index m
, and sum
it all:
my_sums = function(relations, m) {
r = as.matrix(relations)
if(mode(r) != "numeric") mode(r) = "numeric"
sum(m[r])
}
my_sums(relations, m)
(Untested since you didn’t share an m
, but should work fine.)
Answered By – Gregor Thomas
Answer Checked By – Senaida (BugsFixing Volunteer)