3

My ultimate goal is to calculate Clark-Evans-Index (clarkevans.test) for a list of data frames using package spatstat.

So I have a list of my point data:

points.li <- list(structure(list(x.n = c(-1.37977544977995, 0.0787053126116266, 
-6.50583075192879, -9.17021249875416, -19.4146851390704, -22.7380870106472, 
-20.3267566111816, -15.7328116296655, -8.74750043303314, -11.8963575795747
), y.n = c(13.1276911114957, 2.22311850078447, 9.48873515598742, 
2.7986686485412, 2.56632386092958, -0.757078010647191, 6.88269379207495, 
11.5304629645448, 19.131978467755, 28.8757897612883)), row.names = 1098:1107, class = "data.frame", .Names = c("x.n", 
"y.n")), structure(list(x.n = c(0.104714438623701, 1.93357872460516, 
1.51117985822383, 4.47756948027361, 0.710996014054978, -0.727469791776916, 
0.694499984379773, 2.88088318987335, -5.90066975026119, -11.3699018974284
), y.n = c(-5.99908617093835, -9.09677268682439, -12.3075722803524, 
-16.7105167948009, -16.2844860117843, -13.8809505330886, -19.88787745768, 
-20.4985490229505, -14.9797228445106, -17.1780479345837)), row.names = 108:117, class = "data.frame", .Names = c("x.n", 
"y.n")))

> points.li
[[1]]
              x.n       y.n
1098  -1.37977545 13.127691
1099   0.07870531  2.223119
1100  -6.50583075  9.488735
1101  -9.17021250  2.798669
1102 -19.41468514  2.566324
1103 -22.73808701 -0.757078
1104 -20.32675661  6.882694
1105 -15.73281163 11.530463
1106  -8.74750043 19.131978
1107 -11.89635758 28.875790

[[2]]
            x.n        y.n
108   0.1047144  -5.999086
109   1.9335787  -9.096773
110   1.5111799 -12.307572
111   4.4775695 -16.710517
112   0.7109960 -16.284486
113  -0.7274698 -13.880951
114   0.6945000 -19.887877
115   2.8808832 -20.498549
116  -5.9006698 -14.979723
117 -11.3699019 -17.178048

and a list of the plot coordinates:

ref.li <- list(structure(list(x.ref = c(-51.957519, -44.640527, 24.976003, 
17.659011), y.ref = c(39.756418, -29.860112, -22.54312, 47.07341
)), class = "data.frame", row.names = c(NA, -4L), .Names = c("x.ref", 
"y.ref")), structure(list(x.ref = c(15.613798, -52.306902, -35.372372, 
32.548328), y.ref = c(40.306747, 23.372217, -44.548483, -27.613953
)), class = "data.frame", row.names = c(NA, -4L), .Names = c("x.ref", 
"y.ref")))

> ref.li
[[1]]
      x.ref     y.ref
1 -51.95752  39.75642
2 -44.64053 -29.86011
3  24.97600 -22.54312
4  17.65901  47.07341

[[2]]
      x.ref     y.ref
1  15.61380  40.30675
2 -52.30690  23.37222
3 -35.37237 -44.54848
4  32.54833 -27.61395

I created a list of owin objects:

library(spatstat)
bound.li <- lapply(ref.li, function(x) {owin(poly = list(x = x$x.ref, y = x$y.ref))})

> bound.li
[[1]]
window: polygonal boundary
enclosing rectangle: [-51.95752, 24.976] x [-29.86011, 47.07341] units

[[2]]
window: polygonal boundary
enclosing rectangle: [-52.3069, 32.54833] x [-44.54848, 40.30675] units

And now I'd like to create the ppp objects:

pattern.li <- lapply(points.li, function(x) {ppp(x$x.n, x$y.n, window=bound.li)})

resulting in:

Error in verifyclass(window, "owin") : 
  argument ‘window’ is not of class ‘owin’

I don't know if the problem is using a list of owin objects or my incorrect use of lapply with the ppp function as I need to refer to two lists here but don't know how. Any hint how to solve this?

(edit) I also tried

mapply(function(x, y) {ppp(x$x.n, x$y.n, window=y)}, x=points.li, y=bound.li)

but that does not return a list of ppp objects..

erc
  • 10,113
  • 11
  • 57
  • 88
  • 1
    Once you use one of the solutions below you might want to add the spatstat class `solist` (spatial object list) to the result (assuming you named the list `pattern.li`): `pattern.li <- as.solist(pattern.li)`. For instance it automatically makes a layout for you when you plot the entire list of point patterns: `plot(pattern.li)`. – Ege Rubak Mar 15 '16 at 15:41
  • @EgeRubak thanks, that's very interesting and useful! – erc Mar 16 '16 at 15:17

2 Answers2

5

You are passing the whole list of owin objects to the window parameter in ppp. You can use Map instead to iterate over both lists simultaneously. When you attempted mapply it automatically simplified the result. You can also use the SIMPLIFY=FALSE argument for mapply:

Map(function(x, y) {ppp(x$x.n, x$y.n, window=y)}, x=points.li, y=bound.li)
#[[1]]
#Planar point pattern: 10 points
#window: polygonal boundary
#enclosing rectangle: [-51.95752, 24.976] x [-29.86011, 47.07341] units
#
#[[2]]
#Planar point pattern: 10 points
#window: polygonal boundary
#enclosing rectangle: [-52.3069, 32.54833] x [-44.54848, 40.30675] units
Pierre L
  • 28,203
  • 6
  • 47
  • 69
3

Your last suggestion almost works. You just need the argument SIMPLIFY = FALSE:

mapply(function(x, y) {ppp(x$x.n, x$y.n, window=y)}, x=points.li, y=bound.li, SIMPLIFY = FALSE)

Alternatively you can call the function as.ppp with X as your data.frame of point coordinates and W as your owin object:

mapply(as.ppp, X = points.li, W = bound.li, SIMPLIFY = FALSE)
Ege Rubak
  • 4,347
  • 1
  • 10
  • 18
  • The approach by @pierre-lafortune using `Map` seems more modern in the spirit of functional programming, so I have also upvoted that. Actually it seems `Map` in R is just a wrapper to `mapply` avoiding the simplify argument, so you were really on the right track. – Ege Rubak Mar 15 '16 at 15:37