在读取 shapefile 时,
st_read()
中的 sf
包中的 R
命令可以进行 SQL 查询(参见示例 here),但我希望能够包含子查询。
例如,有一个包含美国各州的 shapefile here:
library(sf)
p <- './cb_2018_us_state_20m.shp' #Path
allStates <- st_read(p) #Reads full dataset
#Query for two states
q1 <- 'select * from \"cb_2018_us_state_20m\" where NAME in (\'Oregon\',\'California\')'
twoStates <- st_read(p,query = q1) #Works
如果我想将其作为子查询包含在一个单独的数据框或状态向量中,这将如何工作?我已经尝试了(不成功)SQL 的
in
运算符的各种版本,但它不断返回语法错误:
moreStateNames <- c('Oregon','California','Texas') #Vector of state names
q2 <- 'select * from \"cb_2018_us_state_20m\" where NAME in (\"moreStateNames\")'
moreStates <- st_read(p,query = q2) #Fails
错误:查询执行失败,无法打开图层。另外:警告 消息:在CPL_read_ogr(dsn,层,查询,as.character(选项), 安静,:GDAL 错误 1:“moreStateNames”未被识别为 可用字段。
dfStates <- data.frame(id=1:3,moreStateNames=moreStateNames) #Dataframe with state names
q3 <- 'select * from \"cb_2018_us_state_20m\" where NAME in (select moreStateNames from \"dfStates\")'
moreStates <- st_read(p,query = q3) #Fails
错误:查询执行失败,无法打开图层。另外:警告 消息:在CPL_read_ogr(dsn,层,查询,as.character(选项), 安静,:GDAL错误1:SQL表达式解析错误:语法错误, 意外的选择。发生时间:m“cb_2018_us_state_20m”,其中 NAME(从“dfStates”中选择更多州名称)
我哪里搞砸了?除了读取整个 shapefile 然后事后过滤它之外,我还有什么选择?
在提交查询之前,您需要将向量
moreStateNames
扩展为R中以逗号分隔的字符串。使用 sprintf
可以避免一些引号带来的麻烦:
q2 <- sprintf('select * from \"%s\" where NAME in (\'%s\')',
"cb_2018_us_state_20m",
paste(moreStateNames, collapse = "','")
)
结果:
## > q2
## [1] "select * from \"cb_2018_us_state_20m\" where NAME in ('Oregon','California','Texas')"
这样:
## > moreStates <- st_read(p,query = q2) # Works
## Reading query `select * from "cb_2018_us_state_20m" where NAME in ('Oregon','California','Texas')'
## from data source
## `full\path\to\cb_2018_us_state_20m\cb_2018_us_state_20m.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 3 features and 9 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -124.5524 ymin: 25.84012 xmax: -93.53094 ymax: 46.26913
## Geodetic CRS: NAD83