如何将数据框组成一个简单的特征数据框?

时间:2018-03-08 20:14:44

标签: r sf

我在给定的坐标参考系统中有一个带有地点参考和x和y坐标的表格。我想把它变成一个简单的功能数据框。我该如何创建呢?

我认为可能是:

data_frame(place = "London", 
           lat = 51.5074, lon = 0.1278, 
           epsg = 4326) %>%
  group_by(place) %>%
  mutate(feature = st_point(c(lon, lat)))

但这会导致错误:

  

mutate_impl(.data,dots)中的错误:列feature必须是长度1(组大小),而不是2

这可能很简单,我只是没有在文档中看到它。大多数空间分析师似乎默认要求更好的数据:)。

我还想过尝试:

data_frame(place = "London", 
           lat = 51.5074, lon = 0.1278, 
           epsg = 4326) %>%
  group_by(place) %>%
  do(with(., {
    p <- st_point(c(lon, lat))
    pcol <- st_as_sfc(p)
    st_as_sf(data_frame(place = place,
                        point = pcol),
             crs = epsg)
  }))

在管道的末尾,我想要一个简单的特征数据框架,我可以像其他任何一样绘制和操作。

与我试图做的另一个问题是,我有一个带有EPSG列的数据框。我需要为每个地方创建这个简单的特征数据框,并将它们组合成一个更大的简单特征数据框。

2 个答案:

答案 0 :(得分:3)

您的尝试和被接受的答案不必要地变得复杂且令人困惑。只需使用st_as_sf(顺便说一下,它还可以轻松地从过时的sp类(SpatialPolygonsDataFrames等)中迁移所有对象):

df <- data.frame(place = "London", 
       lat = 51.5074, lon = 0.1278,
       population = 8500000) # just to add some value that is plotable
projcrs <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
df <- st_as_sf(x = df,                         
           coords = c("lon", "lat"),
           crs = projcrs)

就这样完成了。

只需对其进行可视化:

library(tmap)
data("World")    
tm_shape(World[World$iso_a3 == "GBR", ]) + tm_polygons("pop_est") + 
    tm_shape(df) + tm_bubbles("population")

tmap way

或者使用ggplot2中新的令人惊叹的geom_sf

library(ggplot2)
ggplot(World) + geom_sf() + geom_sf(data = df, shape = 4, col = "red", size = 5)

ggplot2 way

答案 1 :(得分:1)

UPDATE @Franz Plumpton的答案是单个epsg 的正确解决方案。我的答案仅在 data.frame的每一行具有不同的epsg 时才有必要。否则,这将是重复的(正如@Henrik上面所指出的那样)。

library(sf)
library(tibble)

df <- data_frame(place = c("London", "Kalamazoo"), 
           lat = c(51.5074, 396088), lon = c(0.1278, 5452158),
           epsg = c(4326, 32610))

l <- lapply(unique(df$place), function(x){
  df <- df[df$place == x,]
  epsg <- df$epsg[1]
  df  <-  st_as_sf(df, coords = c('lon', 'lat'), crs = epsg)
}) 

然后你可以将所有转换为相同的epsg并组合成一个data.frame:

do.call(rbind, lapply(l, function(x) x <- st_transform(x, 4326)))