[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