[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