【问题标题】:R tmap sf Error: arguments imply differing number of rows when viewing mapR tmap sf错误:查看地图时参数暗示不同的行数
【发布时间】:2020-05-30 16:37:40
【问题描述】:

我正在尝试创建每个州所有学区的地图。以下代码适用于所有州,佛罗里达州除外,我收到此错误: data.frame(..., check.names = FALSE) 中的错误: 参数暗示不同的行数:67、121

require(dplyr)
require(sf)
library(tmap)
require(lwgeom)


  temp <- tempfile()  ### create a temporary file to download zip file to
  temp2 <- tempfile() ### create a temporary file to put unzipped files in
  download.file("https://s3.amazonaws.com/data.edbuild.org/public/Processed+Data/SD+shapes/2018/shapefile_1718.zip", temp) # downloading the data into the tempfile

  unzip(zipfile = temp, exdir = temp2) # unzipping the temp file and putting unzipped data in temp2

  filename <- list.files(temp2, full.names = TRUE) # getting the filename of the downloaded data

  shp_file <- filename %>%
    subset(grepl("*.shp$", filename)) ## selecting only the .shp file to read in 

  state_shape <- sf::st_read(shp_file) %>% ## reading in the downloaded data
    dplyr::mutate(GEOID = as.character(GEOID),
                  GEOID = stringr::str_pad(GEOID, width = 7, pad = "0")) %>% 
    filter(State == "Florida")

  url = "https://s3.amazonaws.com/data.edbuild.org/public/Processed+Data/Master/2017/full_data_17_geo_exc.csv"
  master <- read.csv(file = url, stringsAsFactors = FALSE) %>%
    dplyr::mutate(NCESID = as.character(NCESID),
                  NCESID = stringr::str_pad(NCESID, width = 7, pad = "0"),
                  year = "2017") %>%
    dplyr::select(-NAME, -State, -STATE_FIPS) ## removing variables that duplicate with shapes

  state_shape <- state_shape %>%
    dplyr::left_join(master, by = c("GEOID" = "NCESID")) %>% 
    select(GEOID, NAME, State, StPovRate)

  shape.clean <- lwgeom::st_make_valid(state_shape) # making all geometries valid

  povertyBlues <-  c('#dff3fe', '#92DCF0', '#49B4D6', '#2586a5', '#19596d')

  map <- tm_shape(shape.clean) + 
    tm_fill("StPovRate", breaks=c(0, .1, .2, .3, .4, 1), title = "Student Poverty",
            palette = povertyBlues, 
            legend.format=list(fun=function(x) paste0(formatC(x*100, digits=0, format="f"), " %"))) +
    tm_shape(shape.clean) +
    tm_borders(lwd=.25, col = "#e9e9e9", alpha = 1) +
    tm_layout(inner.margins = c(.05,.25,.1,.05)) 

  map  ### view the map

tm_shape$shp 和 state_shape 的长度都是 67。有谁知道是什么原因导致“参数暗示不同的行数:67、121”?

谢谢!!

【问题讨论】:

  • 欢迎来到 Stack Overflow。当您提出任何问题时,您希望提供所有数据以及您的代码。现在,您缺少shape.clean,我相信您的数据包含StPovRate。请提供此数据。否则,没有人可以复制您的情况并思考如何帮助您。
  • state_shape 的几何形状无效;这可以通过lwgeom::st_make_valid() 修复。但是:下载的文件(对于尝试弱连接的人来说是 28 mb)不包含“StPovRate”字段。
  • 我编辑了我的问题,为疏忽添加 StPovRatem 道歉。 Jindra,您是正确的 state_shape 具有无效的几何形状,但不幸的是 st_make_valid 没有修复它。为了清楚起见,我将其添加到示例中。

标签: r spatial sf tmap


【解决方案1】:

我无法使用 tmap 打印这些形状,但我能够手动删除问题点和线,这样它们就不会触发 tmap 中的错误。佛罗里达州和内布拉斯加州都有几何集合,因此我使用以下脚本删除任何线或点并将几何集合更改为多面体。我相信有更好的方法,如果其他人有更优雅的解决方案,我很乐意听到他们的声音。这至少可以让我继续前进!

### Create an st_is function that works for many types
st_is = function(x, type) UseMethod("st_is")

st_is.sf = function(x, type)
  st_is(st_geometry(x), type)

st_is.sfc = function(x, type)
  vapply(x, sf:::st_is.sfg, type, FUN.VALUE = logical(1))

st_is.sfg = function(x, type)
  class(x)[2L] %in% type

####### Correct Florida #########

#### import my florida file
  temp <- tempfile()  ### create a temporary file to download zip file to
  temp2 <- tempfile() ### create a temporary file to put unzipped files in
  download.file("https://s3.amazonaws.com/data.edbuild.org/public/Processed+Data/SD+shapes/2018/shapefile_1718.zip", temp) # downloading the data into the tempfile

  unzip(zipfile = temp, exdir = temp2) # unzipping the temp file and putting unzipped data in temp2

  filename <- list.files(temp2, full.names = TRUE) # getting the filename of the downloaded data

  shp_file <- filename %>%
    subset(grepl("*.shp$", filename)) ## selecting only the .shp file to read in 

  florida <- sf::st_read(shp_file) %>% ## reading in the downloaded data
    filter(State == "Florida")

#### extract polygon shapes from any geometry collection
solution <- for (i in florida) {
  for(j in seq_along(i)) {
    if (class(i[[j]]) != "character" & class(i[[j]]) != "double" & class(i[[j]]) != "numeric") {
      if (st_is.sf(i[[j]], c("GEOMETRYCOLLECTION"))) {
        i[[j]] <- st_collection_extract(i[[j]], type = c("POLYGON"))
      }
      else {
        next
      }
    }
    else {
      next
    }
  }
}

florida_clean <- florida
st_geometry(florida_clean) <- NULL #### remove geometry from original florida
sfc_geo <- sf::st_sfc(i)  #### define i as an sfc
florida_clean$geometry <- sfc_geo  #### attach i to florida
florida_clean <- sf::st_set_geometry( florida_clean, sfc_geo )  ### set florida's geometry as i, with the points and lines removed 

【讨论】:

    【解决方案2】:

    我刚刚遇到了类似的问题,并设法用这里解释的技巧来解决它 https://www.r-spatial.org/r/2017/03/19/invalid.html

    即对无效的形状应用0.0的缓冲区

    p[which(st_is_valid(p)== FALSE),]= st_buffer(p[which(st_is_valid(p)== FALSE),], 0.0)
    

    其中 p 是有问题的层。我希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      我遇到了与 GEOMETRYCOLLECTIONs 与其他几何类型(在我的例子中是 MULTIPOLYGONs)混合的类似问题,产生相同的错误:不同的行数。通过将 GEOMETRYCOLLECTION 解压缩为 POLYGON,然后转换为 MULTIPOLYGON,我得到了一个仅包含 MULTIPOLYGON 的统一空间文件,而不会删除 GEOMETRYCOLLECTION 中包含的特征,也不会出现 tmap 错误。类似于:

      florida <- sf::st_read(shp_file) %>% ## reading in the downloaded data
          filter(State == "Florida") %>%
          st_collection_extract(type = "POLYGON") %>% ##unpacking into POLYGON-type geometries
          st_cast ##type-casting (in this case, st_cast automatically casts to MULTIPOLYGONs)
      

      【讨论】:

        最近更新 更多