Page 1 of 1

How to create the adjacency weights file required to perform CAR spatial

Posted: Sat Aug 13, 2016 12:02 am
by yransome
Dear colleagues,

I have read examples of how to perform a spatial model In runmlwin and all examples have a data set with the weights already included.
For example in the Scottish Lip Cancer example, the required variables are ( neigh1-neigh11) (weights1-weights11) and (wcar1-war11).

##My question is how does one create these variables from your own map? I have yet to find an example explaining how to do this. I got as far as creating the adjacency matrix in Winbugs/Geobugs.

Can anyone please point me on how to create those variables required to use the syntax
runmlwin obs cons perc_aff, ///
> level3(neigh1: cons, mmids(neigh1‐neigh11) mmweights(weight1‐weight11 )) ///
> level2(area:cons) ///
> level1(area:) ///
> discrete(distribution(poisson) link(log) offset(offs)) ///
> mcmc(chain(50000) refresh(500)) initsprevious nopause


## Below is the matrix the "Adjacenc Tool" created, but I am unaware how to convert that into variables


list( num = c(5, 5, 5, 4, 3, 4, 3, 3, 6, 5,
5, 5, 3, 5, 4, 4, 4, 5, 3, 4,
7, 4, 4, 7, 3, 5, 4, 5, 2, 5,
2, 4, 6, 4, 6, 4, 2, 3, 5, 3,
2, 4, 3, 6, 1, 2, 3, 3, 4, 8,
4, 4, 3, 3, 5, 6, 6, 5, 6, 7,
4, 6, 3, 1, 3, 4, 10, 5, 5, 3,
3, 4, 5, 3, 3, 8, 3, 5, 2, 4,
3, 4, 7, 6, 6, 5, 8, 6, 2, 5,
6, 5, 5, 4, 7, 7, 5, 6, 6, 4,
6, 2, 9, 3, 7, 5, 5, 5, 6, 3,
3, 6, 5, 3, 4, 6, 5, 5, 5, 2,
4, 6, 3, 6, 5, 2, 4, 8, 4, 7,
8, 3, 4, 5, 6, 5, 8, 8, 6, 4,
9, 5, 3, 4, 3, 5, 5, 7, 5, 6,
4, 4, 8, 3, 6, 4, 3, 5, 5, 6,
10, 3, 1, 2, 3, 2, 1
),
adj = c(
33, 16, 14, 10, 9,
35, 12, 11, 8, 3,
11, 10, 9, 8, 2,
82, 35, 6, 5,
35, 6, 4,
35, 7, 5, 4,
35, 12, 6,
9, 3, 2,
15, 14, 10, 8, 3, 1,
13, 11, 9, 3, 1,
13, 12, 10, 3, 2,
35, 13, 11, 7, 2,
12, 11, 10,
33, 16, 15, 9, 1,
33, 19, 16, 14,
33, 15, 14, 1,
33, 20, 19, 18,
25, 21, 20, 19, 17,
18, 17, 15,
33, 21, 18, 17,
38, 26, 25, 24, 22, 20, 18,
26, 24, 23, 21,
32, 26, 24, 22,
34, 32, 28, 27, 23, 22, 21,
38, 21, 18,
38, 32, 23, 22, 21,
36, 34, 28, 24,
36, 30, 29, 27, 24,
30, 28,
37, 36, 31, 29, 28,
37, 30,
34, 26, 24, 23,
20, 17, 16, 15, 14, 1,
36, 32, 27, 24,
12, 7, 6, 5, 4, 2,
34, 30, 28, 27,
31, 30,
26, 25, 21,
50, 48, 44, 43, 42,
50, 48, 41,
50, 40,
50, 44, 43, 39,
44, 42, 39,
50, 49, 46, 43, 42, 39,
47,
49, 44,
50, 49, 45,
50, 40, 39,
50, 47, 46, 44,
49, 48, 47, 44, 42, 41, 40, 39,
56, 55, 54, 52,
57, 56, 53, 51,
68, 57, 52,
74, 55, 51,
74, 59, 56, 54, 51,
60, 59, 57, 55, 52, 51,
68, 60, 58, 56, 53, 52,
68, 67, 60, 57, 53,
74, 73, 72, 60, 56, 55,
72, 67, 62, 59, 58, 57, 56,
69, 67, 65, 62,
73, 72, 67, 65, 61, 60,
71, 68, 67,
75,
69, 62, 61,
75, 70, 69, 67,
71, 70, 69, 68, 66, 63, 62, 61, 60, 58,
67, 63, 58, 57, 53,
75, 67, 66, 65, 61,
71, 67, 66,
70, 67, 63,
73, 62, 60, 59,
72, 65, 62, 61, 59,
59, 55, 54,
69, 66, 64,
139, 138, 116, 102, 91, 81, 79, 78,
81, 80, 78,
138, 81, 80, 77, 76,
138, 76,
138, 133, 78, 77,
78, 77, 76,
110, 97, 85, 4,
115, 113, 106, 105, 93, 92, 90,
109, 107, 103, 99, 98, 94,
117, 97, 96, 91, 86, 82,
116, 101, 96, 91, 85,
141, 116, 115, 112, 103, 101, 92, 88,
151, 147, 146, 144, 141, 87,
107, 100,
113, 109, 108, 106, 83,
139, 116, 102, 86, 85, 76,
115, 112, 93, 87, 83,
112, 105, 96, 92, 83,
107, 104, 103, 84,
117, 111, 110, 105, 99, 98, 97,
117, 112, 105, 101, 93, 86, 85,
117, 110, 95, 85, 82,
109, 106, 105, 99, 95, 84,
111, 107, 100, 98, 95, 84,
111, 107, 99, 89,
116, 112, 103, 96, 87, 86,
91, 76,
114, 112, 109, 108, 104, 101, 94, 87, 84,
114, 103, 94,
117, 106, 98, 96, 95, 93, 83,
109, 105, 98, 90, 83,
100, 99, 94, 89, 84,
114, 113, 109, 103, 90,
108, 106, 103, 98, 90, 84,
97, 95, 82,
100, 99, 95,
103, 101, 96, 93, 92, 87,
165, 115, 108, 90, 83,
108, 104, 103,
113, 92, 87, 83,
141, 139, 101, 91, 87, 86,
105, 97, 96, 95, 85,
131, 122, 121, 120, 119,
131, 130, 128, 122, 118,
121, 118,
123, 122, 120, 118,
128, 124, 123, 121, 119, 118,
124, 122, 121,
128, 127, 126, 125, 123, 122,
155, 154, 127, 126, 124,
125, 124,
155, 128, 125, 124,
155, 153, 130, 129, 127, 124, 122, 119,
158, 153, 130, 128,
161, 158, 137, 131, 129, 128, 119,
137, 136, 135, 134, 132, 130, 119, 118,
134, 133, 131,
138, 134, 132, 80,
138, 135, 133, 132, 131,
140, 139, 138, 136, 134, 131,
141, 140, 137, 135, 131,
161, 148, 145, 141, 136, 131, 130, 119,
139, 135, 134, 133, 80, 79, 78, 76,
141, 140, 138, 135, 116, 76,
141, 139, 136, 135,
151, 148, 140, 139, 137, 136, 116, 88, 87,
160, 159, 157, 153, 143,
160, 152, 142,
152, 150, 147, 88,
161, 148, 137,
151, 149, 148, 147, 88,
150, 149, 146, 144, 88,
161, 151, 149, 146, 145, 141, 137,
161, 150, 148, 147, 146,
162, 161, 152, 149, 147, 144,
148, 146, 141, 88,
160, 150, 144, 143,
159, 158, 157, 156, 155, 142, 129, 128,
156, 155, 125,
156, 154, 153, 128, 127, 125,
157, 155, 154, 153,
156, 153, 142,
161, 159, 153, 130, 129,
161, 160, 158, 153, 142,
162, 161, 159, 152, 143, 142,
162, 160, 159, 158, 150, 149, 148, 145, 137, 130,
161, 160, 150,
164,
165, 163,
166, 164, 113,
167, 165,
166
),
sumNumNeigh = 769)

Re: How to create the adjacency weights file required to perform CAR spatial

Posted: Sun Aug 14, 2016 11:55 am
by ChrisCharlton
MLwiN does not have a built-in method of doing this conversion, however as the data generated by WinBUGS appears to be in a form that can be interpreted by R you can do the conversion by writing a function such as the following in R (this assumes that you want equal weights for adjacent areas):

Code: Select all

adj2df <- function(adj) {
    idmat <- matrix(0, length(adj$num), max(adj$num))
    weightmat <- matrix(0, length(adj$num), max(adj$num))
    pos <- 1
    for (i in 1:length(adj$num)) {
        idmat[i, 1:adj$num[i]] <- adj$adj[pos:(pos+adj$num[i]-1)]
        pos <- pos + adj$num[i]
        weightmat[i, 1:adj$num[i]] <- 1 / adj$num[i] 
    }
    colnames(idmat) <- paste0("mmid", 1:ncol(idmat))
    colnames(weightmat) <- paste0("mmweight", 1:ncol(idmat))
    data.frame(cbind(idmat, weightmat))
}
You can load the data in the same format as is output by WinBUGS, assigning it to a new variable:

Code: Select all

adjdata <- list( num = c(5, 5, 5, 4, 3, 4, 3, 3, 6, 5, 
5, 5, 3, 5, 4, 4, 4, 5, 3, 4, 
7, 4, 4, 7, 3, 5, 4, 5, 2, 5, 
2, 4, 6, 4, 6, 4, 2, 3, 5, 3, 
2, 4, 3, 6, 1, 2, 3, 3, 4, 8, 
4, 4, 3, 3, 5, 6, 6, 5, 6, 7, 
4, 6, 3, 1, 3, 4, 10, 5, 5, 3, 
3, 4, 5, 3, 3, 8, 3, 5, 2, 4, 
3, 4, 7, 6, 6, 5, 8, 6, 2, 5, 
6, 5, 5, 4, 7, 7, 5, 6, 6, 4, 
6, 2, 9, 3, 7, 5, 5, 5, 6, 3, 
3, 6, 5, 3, 4, 6, 5, 5, 5, 2, 
4, 6, 3, 6, 5, 2, 4, 8, 4, 7, 
8, 3, 4, 5, 6, 5, 8, 8, 6, 4, 
9, 5, 3, 4, 3, 5, 5, 7, 5, 6, 
4, 4, 8, 3, 6, 4, 3, 5, 5, 6, 
10, 3, 1, 2, 3, 2, 1
),
adj = c(
33, 16, 14, 10, 9, 
35, 12, 11, 8, 3, 
11, 10, 9, 8, 2, 
82, 35, 6, 5, 
35, 6, 4, 
35, 7, 5, 4, 
35, 12, 6, 
9, 3, 2, 
15, 14, 10, 8, 3, 1, 
13, 11, 9, 3, 1, 
13, 12, 10, 3, 2, 
35, 13, 11, 7, 2, 
12, 11, 10, 
33, 16, 15, 9, 1, 
33, 19, 16, 14, 
33, 15, 14, 1, 
33, 20, 19, 18, 
25, 21, 20, 19, 17, 
18, 17, 15, 
33, 21, 18, 17, 
38, 26, 25, 24, 22, 20, 18, 
26, 24, 23, 21, 
32, 26, 24, 22, 
34, 32, 28, 27, 23, 22, 21, 
38, 21, 18, 
38, 32, 23, 22, 21, 
36, 34, 28, 24, 
36, 30, 29, 27, 24, 
30, 28, 
37, 36, 31, 29, 28, 
37, 30, 
34, 26, 24, 23, 
20, 17, 16, 15, 14, 1, 
36, 32, 27, 24, 
12, 7, 6, 5, 4, 2, 
34, 30, 28, 27, 
31, 30, 
26, 25, 21, 
50, 48, 44, 43, 42, 
50, 48, 41, 
50, 40, 
50, 44, 43, 39, 
44, 42, 39, 
50, 49, 46, 43, 42, 39, 
47, 
49, 44, 
50, 49, 45, 
50, 40, 39, 
50, 47, 46, 44, 
49, 48, 47, 44, 42, 41, 40, 39, 
56, 55, 54, 52, 
57, 56, 53, 51, 
68, 57, 52, 
74, 55, 51, 
74, 59, 56, 54, 51, 
60, 59, 57, 55, 52, 51, 
68, 60, 58, 56, 53, 52, 
68, 67, 60, 57, 53, 
74, 73, 72, 60, 56, 55, 
72, 67, 62, 59, 58, 57, 56, 
69, 67, 65, 62, 
73, 72, 67, 65, 61, 60, 
71, 68, 67, 
75, 
69, 62, 61, 
75, 70, 69, 67, 
71, 70, 69, 68, 66, 63, 62, 61, 60, 58, 
67, 63, 58, 57, 53, 
75, 67, 66, 65, 61, 
71, 67, 66, 
70, 67, 63, 
73, 62, 60, 59, 
72, 65, 62, 61, 59, 
59, 55, 54, 
69, 66, 64, 
139, 138, 116, 102, 91, 81, 79, 78, 
81, 80, 78, 
138, 81, 80, 77, 76, 
138, 76, 
138, 133, 78, 77, 
78, 77, 76, 
110, 97, 85, 4, 
115, 113, 106, 105, 93, 92, 90, 
109, 107, 103, 99, 98, 94, 
117, 97, 96, 91, 86, 82, 
116, 101, 96, 91, 85, 
141, 116, 115, 112, 103, 101, 92, 88, 
151, 147, 146, 144, 141, 87, 
107, 100, 
113, 109, 108, 106, 83, 
139, 116, 102, 86, 85, 76, 
115, 112, 93, 87, 83, 
112, 105, 96, 92, 83, 
107, 104, 103, 84, 
117, 111, 110, 105, 99, 98, 97, 
117, 112, 105, 101, 93, 86, 85, 
117, 110, 95, 85, 82, 
109, 106, 105, 99, 95, 84, 
111, 107, 100, 98, 95, 84, 
111, 107, 99, 89, 
116, 112, 103, 96, 87, 86, 
91, 76, 
114, 112, 109, 108, 104, 101, 94, 87, 84, 
114, 103, 94, 
117, 106, 98, 96, 95, 93, 83, 
109, 105, 98, 90, 83, 
100, 99, 94, 89, 84, 
114, 113, 109, 103, 90, 
108, 106, 103, 98, 90, 84, 
97, 95, 82, 
100, 99, 95, 
103, 101, 96, 93, 92, 87, 
165, 115, 108, 90, 83, 
108, 104, 103, 
113, 92, 87, 83, 
141, 139, 101, 91, 87, 86, 
105, 97, 96, 95, 85, 
131, 122, 121, 120, 119, 
131, 130, 128, 122, 118, 
121, 118, 
123, 122, 120, 118, 
128, 124, 123, 121, 119, 118, 
124, 122, 121, 
128, 127, 126, 125, 123, 122, 
155, 154, 127, 126, 124, 
125, 124, 
155, 128, 125, 124, 
155, 153, 130, 129, 127, 124, 122, 119, 
158, 153, 130, 128, 
161, 158, 137, 131, 129, 128, 119, 
137, 136, 135, 134, 132, 130, 119, 118, 
134, 133, 131, 
138, 134, 132, 80, 
138, 135, 133, 132, 131, 
140, 139, 138, 136, 134, 131, 
141, 140, 137, 135, 131, 
161, 148, 145, 141, 136, 131, 130, 119, 
139, 135, 134, 133, 80, 79, 78, 76, 
141, 140, 138, 135, 116, 76, 
141, 139, 136, 135, 
151, 148, 140, 139, 137, 136, 116, 88, 87, 
160, 159, 157, 153, 143, 
160, 152, 142, 
152, 150, 147, 88, 
161, 148, 137, 
151, 149, 148, 147, 88, 
150, 149, 146, 144, 88, 
161, 151, 149, 146, 145, 141, 137, 
161, 150, 148, 147, 146, 
162, 161, 152, 149, 147, 144, 
148, 146, 141, 88, 
160, 150, 144, 143, 
159, 158, 157, 156, 155, 142, 129, 128, 
156, 155, 125, 
156, 154, 153, 128, 127, 125, 
157, 155, 154, 153, 
156, 153, 142, 
161, 159, 153, 130, 129, 
161, 160, 158, 153, 142, 
162, 161, 159, 152, 143, 142, 
162, 160, 159, 158, 150, 149, 148, 145, 137, 130, 
161, 160, 150, 
164, 
165, 163, 
166, 164, 113, 
167, 165, 
166
),
sumNumNeigh = 769)
This function can then be used as follows:

Code: Select all

> adjdf <- adj2df(adjdata)
> head(adjdf)
  mmid1 mmid2 mmid3 mmid4 mmid5 mmid6 mmid7 mmid8 mmid9 mmid10 mmweight1
1    33    16    14    10     9     0     0     0     0      0 0.2000000
2    35    12    11     8     3     0     0     0     0      0 0.2000000
3    11    10     9     8     2     0     0     0     0      0 0.2000000
4    82    35     6     5     0     0     0     0     0      0 0.2500000
5    35     6     4     0     0     0     0     0     0      0 0.3333333
6    35     7     5     4     0     0     0     0     0      0 0.2500000
  mmweight2 mmweight3 mmweight4 mmweight5 mmweight6 mmweight7 mmweight8
1 0.2000000 0.2000000      0.20       0.2         0         0         0
2 0.2000000 0.2000000      0.20       0.2         0         0         0
3 0.2000000 0.2000000      0.20       0.2         0         0         0
4 0.2500000 0.2500000      0.25       0.0         0         0         0
5 0.3333333 0.3333333      0.00       0.0         0         0         0
6 0.2500000 0.2500000      0.25       0.0         0         0         0
  mmweight9 mmweight10
1         0          0
2         0          0
3         0          0
4         0          0
5         0          0
6         0          0
> require(foreign)
> write.dta(adjdf, "adj.dta")
In this example I have saved the final data as a Stata data file, which can then be merged into your Stata data or easily imported into MLwiN. I have attached this file for convenience.

Re: How to create the adjacency weights file required to perform CAR spatial

Posted: Sun Aug 14, 2016 12:22 pm
by ChrisCharlton
Here is an alternative version of the function that sets all the weights to one for use in the CAR model:

Code: Select all

adj2df <- function(adj) {
    idmat <- matrix(0, length(adj$num), max(adj$num))
    weightmat <- matrix(0, length(adj$num), max(adj$num))
    pos <- 1
    for (i in 1:length(adj$num)) {
        idmat[i, 1:adj$num[i]] <- adj$adj[pos:(pos+adj$num[i]-1)]
        pos <- pos + adj$num[i]
        weightmat[i, 1:adj$num[i]] <- 1
    }
    colnames(idmat) <- paste0("mmid", 1:ncol(idmat))
    colnames(weightmat) <- paste0("carweight", 1:ncol(idmat))
    data.frame(cbind(idmat, weightmat))
}
This can be used in the same way:

Code: Select all

> adjdf <- adj2df(adjdata)
> head(adjdf)
  mmid1 mmid2 mmid3 mmid4 mmid5 mmid6 mmid7 mmid8 mmid9 mmid10 carweight1 carweight2 carweight3 carweight4 carweight5 carweight6
1    33    16    14    10     9     0     0     0     0      0          1          1          1          1          1          0
2    35    12    11     8     3     0     0     0     0      0          1          1          1          1          1          0
3    11    10     9     8     2     0     0     0     0      0          1          1          1          1          1          0
4    82    35     6     5     0     0     0     0     0      0          1          1          1          1          0          0
5    35     6     4     0     0     0     0     0     0      0          1          1          1          0          0          0
6    35     7     5     4     0     0     0     0     0      0          1          1          1          1          0          0
  carweight7 carweight8 carweight9 carweight10
1          0          0          0           0
2          0          0          0           0
3          0          0          0           0
4          0          0          0           0
5          0          0          0           0
6          0          0          0           0
> require(foreign)
> write.dta(adjdf, "caradj.dta")
I have again attached the generated Stata file.

Re: How to create the adjacency weights file required to perform CAR spatial

Posted: Wed Aug 24, 2016 10:36 am
by yransome
Dear Chris,

Thank you very much for your extended effort in providing the syntax and data. I will be sure to acknowledge your contribution in any resulting publication.

Warm regards,
Yusuf