不导入大型加拿大Shapefile,如何获取R中变量的可选取值?
问题:不导入大型Shapefile的情况下获取变量可选值
背景
我用R下载了加拿大统计局的大型地理空间Shapefile,代码如下:
# 加载所需包 library(sf) library(rgdal) # 设置Shapefile下载链接 url <- "https://www12.statcan.gc.ca/census-recensement/2011/geo/RNF-FRR/files-fichiers/lrnf000r22a_e.zip" # 创建临时文件夹用于下载和解压 temp_dir <- tempdir() temp_file <- file.path(temp_dir, "lrnf000r22a_e.zip") # 下载文件到临时目录 download.file(url, temp_file) # 解压zip文件 unzip(temp_file, exdir = temp_dir)
因为内存不足没法全量导入文件,我已经用ogrInfo拿到了所有变量的列表:
> ogrInfo(dsn = temp_dir, layer = "lrnf000r22a_e") Source: "C:\Users\me\AppData\Local\Temp\RtmpwXsVlD", layer: "lrnf000r22a_e" Driver: ESRI Shapefile; number of rows: 2246324 Feature type: wkbLineString with 2 dimensions Extent: (3696309 665490.8) - (9015653 4438073) CRS: +proj=lcc +lat_0=63.390675 +lon_0=-91.8666666666667 +lat_1=49 +lat_2=77 +x_0=6200000 +y_0=3000000 +datum=NAD83 +units=m +no_defs LDID: 87 Number of fields: 21 name type length typeName 1 OBJECTID 12 10 Integer64 2 NGD_UID 4 9 String 3 NAME 4 50 String 4 TYPE 4 6 String 5 DIR 4 2 String 6 AFL_VAL 4 9 String 7 ATL_VAL 4 9 String 8 AFR_VAL 4 9 String 9 ATR_VAL 4 9 String 10 CSDUID_L 4 7 String 11 CSDNAME_L 4 100 String 12 CSDTYPE_L 4 3 String 13 CSDUID_R 4 7 String 14 CSDNAME_R 4 100 String 15 CSDTYPE_R 4 3 String 16 PRUID_L 4 2 String 17 PRNAME_L 4 100 String 18 PRUID_R 4 2 String 19 PRNAME_R 4 100 String 20 RANK 4 4 String 21 CLASS 4 4 String
现在想知道:不用把整个文件导入R的前提下,能不能确定这些变量的可选值?比如PRNAME_L/PRNAME_R这类字段,推测是省份名称,取值可能包含"ONTARIO"、"QUEBEC"等。
解决方案
完全可以,不用全量导入就能获取变量的唯一可选值,以下是几种方法:
1. 用GDAL命令行直接查询
如果能访问命令行,直接用ogrinfo命令执行SQL查询,只提取目标字段的唯一值,内存占用极低:
ogrinfo -sql "SELECT DISTINCT PRNAME_L FROM lrnf000r22a_e" "C:\Users\me\AppData\Local\Temp\RtmpwXsVlD"
把PRNAME_L换成你要查的其他字段(比如TYPE、CLASS)就能获取对应可选值。
2. 在R中用sf包执行部分查询
用st_read配合query参数,只加载你需要的字段的唯一值,不用导入整个数据集:
library(sf) # 查询PRNAME_L的唯一值 pr_unique <- st_read( dsn = temp_dir, layer = "lrnf000r22a_e", query = "SELECT DISTINCT PRNAME_L FROM lrnf000r22a_e" ) # 查看结果 print(unique(pr_unique$PRNAME_L))
这种方法只会加载查询结果,内存压力远小于全量导入。
3. 参考官方元数据
你提到的元数据里会有字段的取值说明,比如PRNAME对应的加拿大省份和地区名称,不过直接从数据中查询唯一值会更准确。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

