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

Vijay Lulla vij@ylull@ @ending from gm@il@com
Wed Sep 12 22:06:37 CEST 2018


Maybe the following function is what you're looking for?

getcentroids <- function(x1) {
  getcentroid <- function(x) {
    coords <- slot(x, "coords")
    numrows <- dim(coords)[1]
    ret <- if(numrows == 2) {
      matrix(apply(coords,2,mean), nrow=1)
    } else {
      if(numrows == 1) {
        coords
      } else {
        geosphere::centroid(coords)
      }
    }
    ret
  }

  r <- lapply(x1, function(x) as.data.frame(getcentroid(x)))

  ret <- matrix(unlist(r), ncol=2, byrow=TRUE)
  rownames(ret) <- names(r); colnames(ret) <- c("lon", "lat")

  ret
}

Now call it as lapply(ct, getcentroids)

HTH,
Vijay.

On Wed, Sep 12, 2018 at 2:42 PM Ariel Fuentesdi <ariel.fuentesdi using usach.cl>
wrote:

> 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]]
>
> _______________________________________________
> R-sig-Geo mailing list
> R-sig-Geo using r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>


-- 
Vijay Lulla

Assistant Professor,
Dept. of Geography, IUPUI
425 University Blvd, CA-207C.
Indianapolis, IN-46202
vlulla using iupui.edu
ORCID: https://orcid.org/0000-0002-0823-2522
Webpage: http://vijaylulla.com

	[[alternative HTML version deleted]]



More information about the R-sig-Geo mailing list