New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to go from MULTIPOINT to just point? #114
Comments
Update - works (with warning) for sp objects: y = as(x, "Spatial")
plot(y)
SpatialPoints(y)
|
could
but maybe one could return all points? Or an |
I think returning all points would be good - I imagine the saved I found a way to stop the warning in sp btw - just remove the repeated matrix row names: ropensci/stplanr@52734f7#diff-c451334402a5623377b6bfc78472163dR73 |
Note also: I think I found a bug in sp: |
I think this is not a job for st_cast but a new function, because of the implied 1-to-many aspect (and more generally perhaps the many-to-1 possibilties within aggregate operations). I expect st_cast to work within a mutate() call for example, which would be precluded if st_cast was exploding multis to single rather than "dropping". |
I would go about it something like this, though there's probably more concise ways. This is all standard R data.frame/list idioms, I'm exploring similar techniques for the general cast case (without changing row numbers at the top level). The following assumes there's no mixing, the input is all MULTIPOINT. ## mk multipoint worker
mkmpt <- function(n, mean = 0) st_multipoint(matrix(rnorm(n * 2, mean), ncol = 2))
## mk sf worker
mksf <- function(d, gc) {
stopifnot(nrow(d) == length(gc))
d[["geometry"]] <- gc
st_as_sf(d)
}
## drop geom
drop_geom <- function(x) {
as.data.frame(x)[-match(attr(x, "sf_column"), names(x))]
}
## create a data set
mp <- mksf(data.frame(a = c("a", "b"), b = 1:2), st_sfc(list(mkmpt(10), mkmpt(20, 5))))
## convert multipoint to point
## simple case (it's all multipoint)
mp_to_pt <- function(mp) {
## build map of grouping in geometry
idx <- unlist(lapply(st_geometry(mp), nrow))
## initialize replacement object
## expand out (by duplicating rows for every individual coordinate)
d <- drop_geom(mp)[rep(seq_len(nrow(mp)), idx), ]
rownames(d) <- NULL
## split/explode the multipoints and rebuild
d[["geometry"]] <- st_sfc(unlist(lapply(st_geometry(mp), function(a) lapply(split(a, seq_len(nrow(a))), st_point)), recursive = FALSE, use.names = FALSE),
crs = st_crs(mp))
st_as_sf(d)
}
## do the conversion, MULTIPOINT sf to POINT sf with auto-one-to-many expansion
mp_to_pt(mp) I think there's a nice case for a general decomposition to rows-per part, but it's got complications - like holes being elevated to islands, so I'm not sure how much of this will belong in sf directly. |
How about an |
Both sound good, but I like the one with |
Here's some draft code that un-multipoints:
|
I think this is equivalent to |
We now have:
As it is now, |
Update: this is still not working: # test multipoint to point conversion
x = st_multipoint(matrix(1:10, ncol = 2))
st_cast(x = x, to = "POINT")
|
I was expecting 5 points, that can get ids associated. Equivalent sp code: p = sp::SpatialPoints(matrix(1:10, ncol = 2)) How does one do that in sf? |
From scratch: d <- as.data.frame(matrix(1:10, ncol = 2))
d$id <- 1:5
st_as_sf(d, coords = c("V1", "V2")) But the casting method also works if it's st_cast(st_sfc(x), "POINT") Compare when the st_cast(st_sfc(x), "POINT", group_or_split = FALSE) |
Thanks for the clarification - I missed out the |
Question on this @edzer: how to create a library(sf)
set.seed(1985)
m3 = matrix(runif(10), ncol = 2)
mp = st_multipoint(x = m3)
p = st_cast(x = mp, to = "POINT") At the moment I'm getting this useful warning but no indication of how to make it include all points: #> Warning in st_cast.MULTIPOINT(x = mp, to = "POINT"): point from first |
You can't create a p = st_cast(x = st_sfc(mp), to = "POINT") |
Thanks - makes sense. This if for some documentation of the new |
Is there a PR, or one in the works, for st_un_multipoint? |
Is |
My bad - I thought from first reading the discussion that there was a problem with using casting for this case. |
Reproducible example:
Is there a function, e.g.
as.st_points
that could convert this into just points? If not any ideas of the best way to go about creating such a function?The text was updated successfully, but these errors were encountered: