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

Ariel Fuentesdi @riel@fuente@di @ending from u@@ch@cl
Wed Sep 12 23:09:45 CEST 2018


I understand, but I said "it doesn't work" because it gave an undesired
solution, but I'll try to be more explicit next time.
And I forgot to say that: s  <- 1: length(ct)

And thank you for your advice, but the answer of Vijay Lulla resolved my
problem.

Regards,
Ariel

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

> On any R mailing list, whenever you say "it doesn't work", you should
> always copy exactly what R command you gave, and any error messages.
>
> First notice:
>
> > ct$a$two
> SpatialPoints:
>      lon lat
> [1,] -18  -2
> [2,] -16  50
> Coordinate Reference System (CRS) arguments: NA
>
> Then compare these:
>
> > coordinates(ct$a$two)
>      lon lat
> [1,] -18  -2
> [2,] -16  50
>
> > coordinates(slot(ct$a$two,'coords'))
>      lon lat
> [1,] -18  -2
> [2,] -16  50
>
> The results are the same. Why are you using the slot() function? There is
> no need, and it makes it more difficult to understand.
>
>
> You have assumed the mean() function will give you what you want when
> there are two points. It doesn't. Try it and see:
>
> > mean( coordinates(ct$a$two))
> [1] 3.5
>
> > mean(coordinates(slot(ct$a$two,'coords')))
>  [1] 3.5
>
> Replace the mean() function with a function that will give you the
> "centroid" of two points, however you want to define that centroid. Perhaps
> the means of the two columns? R has a function for that.
>
> -----------------
> In this bit:
>
> ctply <- lapply(X = s, FUN = function(x) sapply(X = ct[[x]],
>                                                     FUN = function(y)
>
> Using X = s is wrong because you haven't defined or created s anywhere. X
> should be ct.
>
> Also, X = ct[[x]] is wrong. When the first FUN is executed, it will be
> supplied automatically with the whole of ct$a, then ct$b. Try
>
> ctply <- lapply(X = s, FUN = function(x) sapply(X = x,
>                                                     FUN = function(y)
>
> The whole thing is easier to understand and test if you define the
> functions outside the lapply and sapply calls.
>
> -Don
> --
> Don MacQueen
> Lawrence Livermore National Laboratory
> 7000 East Ave., L-627
> Livermore, CA 94550
> 925-423-1062
> Lab cell 925-724-7509
>
>
>
> On 9/12/18, 11:42 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:
>
>     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
>
>
>

	[[alternative HTML version deleted]]



More information about the R-sig-Geo mailing list