EmilBB - 8 months ago 46

R Question

I have a matrix, which represents mobility between various jobs:

`jobdat <- matrix(c(`

295, 20, 0, 0, 0, 5, 7,

45, 3309, 15, 0, 0, 0, 3,

23, 221, 2029, 5, 0, 0, 0,

0, 0, 10, 100, 8, 0, 3,

0, 0, 0, 0, 109, 4, 4,

0, 0, 0, 0, 4, 375, 38,

0, 18, 0, 0, 4, 26, 260),

nrow = 7, ncol = 7, byrow = TRUE,

dimnames = list(c("job 1","job 2","job 3","job 4","job 5","job 6","job 7"),

c("job 1","job 2","job 3","job 4","job 5","job 6","job 7")))

This is treated as a directed, weighted adjacency matrix in a social network analysis.

The direction of the network is from rows to columns: So mobility is defined as going from a job-row to a job-column. The diagonal is meaningful, since it is possible to change to the same job in another firm.

For part of my analysis I want to select a submatrix which consists of job 1, job 5 and job 7:

`work.list <- c(1,5,7)`

jobpick_wrong <- jobdat[work.list,work.list]

however, this only gives the direct ties between these three jobs. What I need is this:

`jobpick_right <- matrix(c(`

295, 20, 0, 5, 7,

45, 3309, 0, 0, 3,

0, 0, 109, 4, 4,

0, 0, 4, 375, 38,

0, 18, 4, 26, 260),

nrow = 5, ncol = 5, byrow = TRUE,

dimnames = list(c("job 1","job 2","job 5","job 6","job 7"),

c("job 1","job 2","job 5","job 6","job 7")))

Here, job 2 and 6 are also included, since these two jobs also have direct ties to either job 1, 5 or 7. While job 3 and 4 are excluded, because they do not have any ties to job 1, 5 or 7.

I'm not sure how to go about this. Maybe I have to transform it into an igraph-object in order to get anywhere?

`net <- graph.adjacency(jobdat, mode = "directed", weighted = TRUE)`

and then maybe use the ego/neighborhood-function, also from the igraph package? But how I'm really not sure how. Or if this is the best way to go about it.

Thank you for your time,

Emil Begtrup-Bright

Answer

Assuming your directed graph is from rows to columns, what you can do is to augment your `work.list`

with those columns that are connected (with element !=0) to each row in the `work.list`

. You can do this by:

```
work.list <- sort(unique(unlist(lapply(work.list, function(x) which(jobdat[x,] != 0)))))
```

Use `unique`

to keep only the unique columns assembled and `sort`

so that these columns are sorted by their indices. Then:

```
jobdat[work.list,work.list]
## job 1 job 2 job 5 job 6 job 7
##job 1 295 20 0 5 7
##job 2 45 3309 0 0 3
##job 5 0 0 109 4 4
##job 6 0 0 4 375 38
##job 7 0 18 4 26 260
```

If instead, your directed graph is from columns to rows:

```
work.list <- sort(unique(unlist(lapply(work.list, function(x) which(jobdat[,x] != 0)))))
```

Source (Stackoverflow)