[R-sig-Geo] help: Problem getting centroids inside lists

Ariel Fuentesdi @riel@fuente@di @ending from u@@ch@cl
Wed Sep 12 20:41:31 CEST 2018


I went to a more general approach, that is:

ctply <- lapply(X = s, FUN = function(x) sapply(X = ct[[x]],
          FUN = function(y) if(length(y)>1) geosphere::centroid(slot(y,
"coords"))
          else sp::coordinates(slot(y, "coords"))))

But now I want to add the case when they are only two elements. The dataset
will be:

ct <- list(a = list(one = data.frame(lon = c(-180, -160, -60), lat = c(-20,
5, 0)),
                    two = data.frame(lon = c(-18, -16), lat = c(-2, 50))),
           b = list(one = data.frame(lon = c(-9, -8, -3), lat = c(-1, 25,
5)),
                    two = data.frame(lon = c(-90), lat = c(-1))))
coordinates(ct$a$one) <- ~lon+lat
coordinates(ct$a$two) <- ~lon+lat
coordinates(ct$b$one) <- ~lon+lat
coordinates(ct$b$two) <- ~lon+lat

And I did the following but it doesn't work:

ctply <- lapply(X = s, FUN = function(x) sapply(X = ct[[x]],
                                                FUN = function(y)
if(length(y)>2) geosphere::centroid(slot(y, "coords"))
                                                else if (length(y) == 1)
sp::coordinates(slot(y, "coords"))
                                                else
mean(sp::coordinates(slot(y, "coords")))))

I need the result of each element of the list will be a matrix of two rows
per column (named: one, two). How do I fix it?

Regards,
Ariel

2018-09-10 17:29 GMT-03:00 MacQueen, Don <macqueen1 using llnl.gov>:

> If all of your data frames had enough points then this should work:
>
> myfun1 <- function(le) {
>   list(one=geosphere::centroid(coordinates(le$one)),
>        two=geosphere::centroid(coordinates(le$two))
>        )
> }
>
> lapply(ct, myfun1)
>
> To handle the one point case, try the following, which I think works with
> your example data, but is untested if there just two points.
> It also assumes the data frames are named 'one' and 'two', and will ignore
> any others. To handle other names, I think you
> could replace  $one  with  [[1]]  and  $two  with  [[2]]  .
>
> myfun <- function(le) {
>   list(one=if (length(le$one)>1) geosphere::centroid(coordinates(le$one))
> else coodinates(le$one),
>        two=if (length(le$two)>1) geosphere::centroid(coordinates(le$two))
> else coordinates(le$two)
>        )
> }
>
> lapply(ct, myfun)
>
>
> To see a little bit of what's going on, try
>
>   myfun(ct[[1]])
>   myfun1(ct[[1]])
>   myfun1(ct[[2]])
>   myfun(ct[[2]])
>
>
>
> I would also verify that the length method for objects of class
> SpatialPoints does return the number of points, as it appears to:
>
> > class(ct$a$two)
> [1] "SpatialPoints"
> attr(,"package")
> [1] "sp"
>
> > length(ct$a$one)
> [1] 3
> > length(ct$a$two)
> [1] 3
> > length(ct$a$two)
> [1] 3
> > length(ct$b$two)
> [1] 1
>
> --
> Don MacQueen
> Lawrence Livermore National Laboratory
> 7000 East Ave., L-627
> Livermore, CA 94550
> 925-423-1062
> Lab cell 925-724-7509
>
>
>
> On 9/10/18, 10:56 AM, "R-sig-Geo on behalf of Ariel Fuentesdi" <
> r-sig-geo-bounces using r-project.org on behalf of ariel.fuentesdi using usach.cl>
> wrote:
>
>     Hi everyone,
>
>     I have a list of coordinates called "ct" and I want to extract the
>     centroids of each sublist, but it only works when it has only 3 or more
>     points. In ct$b$two only has one point; in that case, I would rescue
> that
>     point as If it were a centroid.
>
>     This is what I did:
>
>     library(dplyr)
>     library(geosphere)
>
>     ct <- list(a = list(one = data.frame(lon = c(-180, -160, -60), lat =
> c(-20,
>     5, 0)),
>                         two = data.frame(lon = c(-18, -16, -6), lat =
> c(-2, 50,
>     10))),
>                b = list(one = data.frame(lon = c(-9, -8, -3), lat = c(-1,
> 25,
>     5)),
>                         two = data.frame(lon = c(-90), lat = c(-1))))
>
>     coordinates(ct$a$one) <- ~lon+lat
>     coordinates(ct$a$two) <- ~lon+lat
>     coordinates(ct$b$one) <- ~lon+lat
>     coordinates(ct$b$two) <- ~lon+lat
>
>     s <- 1:length(ct)
>     ctply <- list()
>     for (i in s){
>      for (j in 1:length(ct[[i]])) {
>       ctply[[i]][j] <- ifelse(test = lengths(ct[[i]][1]) > 2, yes =
> sapply(X =
>     ct[[i]][j],
>         FUN = function(y) geosphere::centroid(slot(y, "coords"))), no =
>     ct[[i]][j] )
>      }
>     }
>
>     Thanks in advance
>
>     Regards,
>     Ariel
>
>         [[alternative HTML version deleted]]
>
>     _______________________________________________
>     R-sig-Geo mailing list
>     R-sig-Geo using r-project.org
>     https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>
>
>

	[[alternative HTML version deleted]]



More information about the R-sig-Geo mailing list