R tmap sf Error: arguments imply differing number of rows when viewing map

R tmap sf Error: arguments imply differing number of rows when viewing map

我正在尝试创建每个州所有学区的地图。下面的代码适用于所有州,除了在佛罗里达州我收到此错误: 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。有谁知道是什么导致了 "arguments imply differing number of rows: 67, 121"?

谢谢!!

我无法使用 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 

我刚刚遇到了类似的问题,并设法用这里解释的技巧解决了它 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 是所讨论的图层。希望对您有所帮助。

我遇到了与 GEOMETRYCOLLECTION 与其他几何类型(在我的情况下为 MULTIPOLYGON)混合相关的类似问题,产生了相同的错误:不同的行数。通过将 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)