在处理空间矢量对象时,有时需要为它们增加新的属性数据。属性数据可以有两个来源:一是根据矢量对象各要素已有的数据进行信息匹配;二是利用空间位置关系把其他矢量对象的属性数据传递过来。前者是非空间方法,后者是空间方法。

在ArcGIS中,Join Data的下拉框提供了这两种属性连接方式,如下图:

在R语言的sf工具包中:

  • 非空间方法的思路与普通数据框的连接操作一样,主要使用dplyr包的join系列函数。相关函数方法在之前的推文中已经有所介绍:dplyr | 数据导入和预处理的常用函数。

  • sf包中的st_join()函数则使用的是空间方法。这个函数依赖于一系列用于判断几何要素空间位置关系的函数,详见之前的推文:sf | 判断点线面等几何对象的空间位置关系。

1 非空间方法

前面说过,sf对象的数据结构是一个特殊的数据框,许多针对数据框的函数同样可以应用于它。dplyr的join系列函数可以将普通数据框内的数据通过共同变量传递给sf对象。

*_join.sf(x, y, by = NULL, copy = FALSE, suffix = c(".x", ".y"), ...)
  • join系列函数包括left_join()right_join()full_join()inner_join()semi_join()anti_join()等,函数功能见前推文dplyr | 数据导入和预处理的常用函数;

  • 该系列函数不能用于两个矢量对象的属性连接,也就是说x可以是sf对象,但y只能为普通数据框;

  • sf包的说明文档里为这些函数添加了后缀.sf,但在使用时需要去掉后缀,并且仍然需要提前加载tidyverse包或dplyr包。

基础包base中的merge()函数也可以实现类似的功能。语法结构如下:

merge(x, y, by = intersect(names(x), names(y)), by.x = by, by.y = by,all = FALSE, all.x = all, all.y = all,sort = TRUE, suffixes = c(".x",".y"), no.dups = TRUE, incomparables = NULL, ...)
  • 与join系列函数一样,merge()函数也要求y是普通数据框;

  • 当连接变量在x和y同名时可以使用by参数,该参数默认值是全部同名变量;如果连接变量不同名,则使用by.x和by.y分别指定变量名;

  • all默认为FALSE,表示只保留x中能够与y匹配的几何要素(sf对象每行代表一个几何要素),这一点与join系列函数有所区别;当设置为TRUE时,则保留x中的所有几何要素,缺失值记为NA;all.x和all.y分别针对x和y做类似的处理,默认与参数all一致;

  • sort控制按照匹配变量排序。

y必须为普通数据框,不能是sf对象,否则会报错

library(tidyverse)
library(sf)nc <- st_read(system.file("shape/nc.shp", package = "sf"))
ync <- select(nc, FIPS) %>% mutate(var = rpois(100, 10))
class(ync)
ync2 <- st_drop_geometry(ync)  # 删去几何信息,变成普通数据框
class(ync2)a1 <- left_join(nc, ync, by = "FIPS")
a2 <- merge(nc, ync)
# 部分输出结果
> class(ync)
[1] "sf"         "data.frame"> class(ync2)
[1] "data.frame"

当连接变量在x和y中同名时,merge()的by参数有默认值

# 连接变量在nc和ync2中都叫FIPS
b1 <- left_join(nc, ync2, by = "FIPS")
b2 <- merge(nc, ync2)# 修改ync2的FIPS的列名后再连接
ync3 <- rename(ync2, NewFIPS = FIPS)
b3 <- left_join(nc, ync3, by = c("FIPS" = "NewFIPS"))
b4 <- merge(nc, ync3, by.x = "FIPS", by.y = "NewFIPS")

除了连接函数,列拼接函数也可以用于属性连接,但这要求x和y对应行的顺序必须一致

  • 当x和y均为sf对象时,推荐使用基础包base中的cbind()函数;

  • 当y为普通数据框时,推荐使用dplyr中的bind_cols()函数;

  • sf包自建的st_bind_cols()函数是通用函数,但该函数已被停止维护了。

# y为sf对象
c1 <- bind_cols(nc, ync)
c2 <- cbind(nc, ync)  # 推荐
c3 <- st_bind_cols(nc, ync) # y为普通数据框
d1 <- bind_cols(nc, ync2)  # 推荐
d2 <- rbind(nc, ync2)
d3 <- st_bind_cols(nc, ync2)

使用行拼接函数,可以实现矢量数据的合并操作

合并(append)操作在ArcGIS中的示意图如下:

在R中,可以使用行拼接函数实现这一操作,并且使用dplyr中的bind_rows()函数和base中的rbind()函数效果一样。

library(tidyverse)
library(sf)nc <- st_read(system.file("shape/nc.shp", package = "sf"))
min_nc <- filter(nc, AREA < 0.1)
max_nc <- filter(nc, AREA > 0.2)e1 <- bind_rows(min_nc, max_nc)
e2 <- rbind(min_nc, max_nc)
identical(e1,e2)  # e1和e2完全相同par(omi = c(0,0,0,0))
par(mfrow = c(1,2))
plot(st_geometry(min_nc), main = "输入1")
plot(st_geometry(max_nc), main = "输入2")
par(mfrow = c(1,1))
plot(st_geometry(e1), main = "输出")

2 空间方法

2.1 st_join()

sf包中的st_join()使用空间位置关系在两个矢量对象之间传递属性信息。其语法结构如下:

st_join(x, y, join = st_intersects, ...,suffix = c(".x", ".y"), left = TRUE, largest = FALSE
)

参数说明:

  • 输入对象x和y均需是sf格式;

  • join参数为判断点线面位置关系的函数,详见推文sf | 判断点线面等几何对象的空间位置关系,...为继承自这些函数的参数;

  • 工作原理:以x和y中的几何要素为最小单位,按照参数join引用的空间位置判断函数判断x的各几何要素对y的各几何要素的位置关系,当符合该位置关系时就将y中的属性数据传递给对应x的几何要素;

  • suffix参数用于x和y中有同名变量时区分来源;

  • left为TRUE时,输出结果保留x的所有几何要素;当设置为FASLE时,输出结果只保留能够连接的几何要素;

  • largest设置为TRUE时,若x中的要素能与多个y内的几何要素连接,则只将面积最大的几何要素信息传递给相应x的几何要素。

生成示例文件(参考官方说明文档):

library(tidyverse)
library(sf)st_read(system.file("shape/nc.shp", package="sf")) %>%select(FIPS) %>%st_transform(2264) -> ncst_sf(label = apply(expand.grid(1:10, LETTERS[10:1])[,2:1], 1, paste0, collapse = " "),geom = st_make_grid(st_as_sfc(st_bbox(nc)))) -> ncgrid
ncgrid$col = sf.colors(10, categorical = TRUE, alpha = 0.3)# 绘图
plot(st_geometry(nc), lwd = 1.5, key.pos = NULL, main = "nc")
plot(st_geometry(ncgrid), col = ncgrid$col, main = "ncgrid")
text(st_coordinates(st_centroid(ncgrid)), labels = ncgrid$label)

nc的属性变量记录的是美国北卡罗来纳州(North Carolina)各县的FIPS编码;ncgrid是根据nc的范围创建的方格型矢量对象,其包含属性变量labels和颜色colncncgrid分别有100行数据。

nc

ncgrid

x中某几何要素能与几个y中的几何要素相连接,输出结果中该几何要素就占据几行,每行对应一个y中几何要素的属性数据,这样输出结果的行数可能会大于x的行数

比如,ncncgrid均包含100行数据,但下面代码的输出结果远大于100行数据:

nc1 <- st_join(nc, ncgrid)
dim(nc1)
# 部分输出结果
> dim(nc1)
[1] 349   4

为了使输出结果中每个几何要素只占据一行,需要进行“聚合”操作:

  • 对于数值型变量,可以使用summarise()aggregate()函数,这会在后续文章中单独介绍;

  • 对于非数值型变量,在使用st_join()时可以将largest参数设置为TRUE。

nc2 <- st_join(nc, ncgrid, largest = T)# 颜色col
plot(st_geometry(nc2), lwd = 1.5, col = nc2$col)
plot(st_geometry(ncgrid), add = T)

left参数设置为FASLE可以将没有连接关系的几何要素删去

比如ncgrid有的质心不能落到任何一个nc的要素中:

# 获取ncgrid的质心
ncpoints <- st_centroid(ncgrid)nc3 <- st_join(ncpoints, nc, left = F)
dim(nc3)
# 部分输出结果
> dim(nc3)
[1] 55  4

可以看出,输出的nc4只剩下55行数据了。

join参数可以根据需要选择相离、相切、相交和包含函数

# 使用包含函数
nc4 <- st_join(ncpoints, nc, join = st_within, left = F)
nc5 <- st_join(ncgrid, nc4, join = st_contains)
dim(nc5)plot(st_geometry(nc), lwd = 1.5)
plot(st_geometry(ncgrid), col = nc5$col.y, add = T)
# 部分输出结果
> dim(nc5)
[1] 100   6

试比较和上幅图的区别

2.2 st_filter()

st_filter(x, y, ..., .predicate = st_intersects)
  • 该函数是空间筛选函数,它的.predicate参数相当于st_join()的join参数;

  • 该函数主要是将x中符合相应位置关系的几何要素筛选出来,而不会进行属性传递。

nc6 <- st_filter(ncpoints, nc, .predicate = st_within)
dim(ncpoints)
dim(nc6)
# 部分输出结果
> dim(ncpoints)
[1] 100   3
> dim(nc6)
[1] 55  3

可以看出nc5中行数相比于ncpoints变少了,但列数(变量数)未变。

st_filter()一般不会直接引用相离函数

由于一般x中的几何要素总会与y中的一些几何要素具有相离关系,因此直接使用相离函数达不到筛选的目的。

为了筛选出x中与y整体相离的几何要素,可以使用st_combine()函数将y转换成具有整体意义的对象。需要注意的是,转换后的sf对象会变成一个list,不再具备数据框的特征。

比如筛选出没有落入nc范围内的质心:

# 不能达到筛选目的
nc7 <- st_filter(ncpoints, nc, .predicate = st_disjoint)
dim(nc7)# 可以达到筛选目的
nc8 <- st_filter(ncpoints, st_combine(nc), .predicate = st_disjoint)
dim(nc8)
# 部分输出结果
> dim(nc7)
[1] 100   3> dim(nc8)
[1] 45  3

sf | 空间矢量对象的属性连接方法相关推荐

  1. sf | 空间矢量对象的几何信息处理方法

    本篇介绍sf包的一些函数方法,这些函数方法都是用于处理空间矢量对象的几何信息. 提取对象几何信息 st_bbox:提取对象的地理或投影坐标范围: st_area:提取对象的各要素面积: st_leng ...

  2. sf | 空间矢量对象的“聚合”操作

    前面介绍空间连接函数时(sf | 空间矢量对象的属性连接方法)提到,对于数值型属性,要想将属性连接后的几何要素在sf对象中整合成一行,需要额外执行"聚合"操作.所谓"聚合 ...

  3. sf | 创建空间矢量对象及其投影设置

    R语言的空间数据主要有sp和sf两种格式.本篇介绍使用sf工具包中的相关函数创建sf格式的空间矢量对象,以及设置和转换矢量对象的投影坐标信息. 1 创建空间矢量对象 1.1 sf对象的组成 sf对象是 ...

  4. [置顶] 深入浅出Javascript(三)创建自定义对象以及属性、方法

    怎么样创建一个对象? 利用Object创建自定义对象 JavaScript能够自定义对象来扩展程序的功能,不仅如此,它还能扩展JavaScript提供的内置对象,新增内置对象的属性或方法 例如下面代码 ...

  5. Jquery jqXHR对象的属性和方法

    在 jQuery 1.4 之前(包括1.4),$.ajax() 方法返回的是浏览器原生的 XMLHttpRequest 对象. 从 jQuery 1.5 开始,$.ajax() 方法返回 jQuery ...

  6. JavaScript中的高级特性及特别对象、属性和方法

    一,编写构造函数    可以使用 new 运算符结合像 Object().Date() 和 Function() 这样的预定义的构造函数来创建对象并对其初始化.面向对象的编程其强有力的特征是定义自定义 ...

  7. 7.1.3 Python进阶 《函数》定义、调用,参数,返回值《面向对象》概念,类,实例,对象,属性,方法《模块、包》导入,自定义,常用内置:datatime,time,random,os,sys

    目录 ======== 第四部分 Python进阶 ======== 第一节 函数 4.1.1 函数定义及调用 4.1.2 函数的参数 4.1.3 函数的返回值 第二节 面向对象 4.2.1 面向对象 ...

  8. ASP.NET基础教程-DataView对象的属性、方法、枚举成员

    DataView对象用于通过过滤器查看DataTable对象中的特定行.也可以排序用DataView查看的行.可以增加.修改与删除DataView中的行,这些改变也适用于DataView将从中进行读取 ...

  9. HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次)

    HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次) 一.总结 一句话总结:目录就是测试题 1.document取得元素(get element)的方式有哪几种? 解答:四种,分别是id ...

最新文章

  1. 数据中心行业在能源转型中将发挥重要作用
  2. Git学习笔记:Git简介
  3. linux算法设计,红黑树的原理分析和算法设计
  4. addition过程 sgnb_5G NR接入优化问题排查思路
  5. (18)VHDL实现译码器
  6. 表单嵌套问题的解决方法
  7. 《OD学hadoop》第二周0703
  8. 内网穿透干货教程,1分钟极速穿透内网端口
  9. 数字信号处理基础----采样定理
  10. Android O 自定义通知实例及一个自定义自动适配缩放图片至特定大小的田字格ImageView
  11. Android通过来电号码识别姓名。
  12. Win10开启ssh和scp
  13. ulimit -u
  14. WLT8016:BLE蓝牙的一些基本概念
  15. 计算机网络设备调试员报名,工信部网络设备调试员一级高级技师、二级技师
  16. 微信、支付宝支付绑定多个商户号
  17. (转)日语汉字音便规则
  18. 四阶及以上魔方公式技巧大全
  19. 快速上手搜索引擎的秘密武器——Lucene
  20. osmdroid地图

热门文章

  1. 用vb打开word excel 文件,出现提示“发现不可读取的内容”
  2. Java Web学习总结(43)—— Restful API 版本控制
  3. Kubernetes学习总结(6)——Kubernetes 7周年:它为什么如此受欢迎?
  4. Linux学习总结(19)——Linux中文本编辑器vim特殊使用方法
  5. Git学习总结(14)——Git使用前的注意事项
  6. 网站的服务器怎么维护,网站服务器怎么维护
  7. php类方法属性省略,第十课—类的属性和类的方法 2018年9月3日 20时00分
  8. mean shift 图像分割(一、二、三)
  9. PHP如何判断提交表单中多个复选框是否选中?
  10. TYVJ P1083 分糖果 Label:bfs