具有MRF平滑功能的GAM-错误(nb /多边形区域名称与数据区域名称不匹配

时间:2019-06-11 11:20:44

标签: r mgcv spdep

在@GavinSimpson的精彩博客之后,我正努力适应2015年波兰地方政府选举结果。 https://www.fromthebottomoftheheap.net/2017/10/19/first-steps-with-mrf-smooths/我将xls的shp数据与6位数字的标识符(可能以0开头)结合在一起。我将其保留为文本变量。编辑,我简化了标识符,现在使用从1到n的序列来简化我的问题。

'data.frame':   18528 obs. of  1365 variables:
 $ idauniq             : int  100001 100005 100006 100007 100009 100010 100012 100016 100018 100021 ...
 $ age_1               : int  NA NA NA NA NA NA NA NA NA NA ...
 $ age_2               : int  52 NA NA 56 NA NA NA NA 50 54 ...
 $ age_3               : int  54 NA NA 58 66 NA 58 55 52 56 ...
 $ age_4               : int  56 NA 57 60 68 NA 60 57 NA NA ...
 $ age_5               : int  58 64 59 62 70 NA 62 NA NA 60 ...
 $ age_6               : int  NA NA 61 64 72 NA NA NA NA 62 ...
 $ age_7               : int  63 NA NA 66 74 NA NA NA NA NA ...
 $ age_8               : int  NA NA NA 68 NA NA 69 NA NA NA ...
 $ sex                 : int  1 1 1 1 1 1 1 2 1 2 ...
 $ education           : int  1 1 1 1 1 1 2 NA 3 2 ...
 $ dementia_1          : ini  1 0 1 1 1 1 2 NA 1 NA ...

这是错误消息:

library(tidyverse)
library(sf)
library(mgcv)

# Read data
# From https://www.gis-support.pl/downloads/gminy.zip shp file

boroughs_shp <- st_read("../../_mapy/gminy.shp",options = "ENCODING=WINDOWS-1250",
                     stringsAsFactors = FALSE ) %>% 
  st_transform(crs = 4326)%>% 
  janitor::clean_names() %>% 
# st_simplify(preserveTopology = T, dTolerance = 0.01) %>% 
  mutate(teryt=str_sub(jpt_kod_je, 1, 6)) %>% 
  select(teryt, nazwa=jpt_nazwa, geometry)

# From https://parlament2015.pkw.gov.pl/wyniki_zb/2015-gl-lis-gm.zip data file
elections_xls <-
  readxl::read_excel("data/2015-gl-lis-gm.xls",
             trim_ws = T, col_names = T) %>% 
  janitor::clean_names() %>% 
  select(teryt, liczba_wyborcow, glosy_niewazne)

elections <-
  boroughs_shp %>% fortify() %>% 
  left_join(elections_xls, by = "teryt") %>% 
  arrange(teryt) %>%
  mutate(idx = seq.int(nrow(.)) %>% as.factor(), 
         teryt = as.factor(teryt)) 

# Neighbors

boroughs_nb <-spdep::poly2nb(elections, snap = 0.01, queen = F, row.names = elections$idx )
names(boroughs_nb) <- attr(boroughs_nb, "region.id")

# Model

ctrl <- gam.control(nthreads = 4) 
m1 <- gam(glosy_niewazne ~ s(idx, bs = 'mrf', xt = list(nb = boroughs_nb)), 
          data = elections,
          offset = log(liczba_wyborcow), # number of votes
          method = 'REML', 
          control = ctrl,
          family = betar()) 

elections $ idx是一个因素。我正在使用它为boroughs_nb命名,以确保我具有相同数量的级别。我在做什么错了?

编辑:满足错误消息中提到的条件:

    Error in smooth.construct.mrf.smooth.spec(object, dk$data, dk$knots) : 
  mismatch between nb/polys supplied area names and data area names
In addition: Warning message:
In if (all.equal(sort(a.name), sort(levels(k))) != TRUE) stop("mismatch between nb/polys supplied area names and data area names") :
  the condition has length > 1 and only the first element will be used

1 个答案:

答案 0 :(得分:0)

看来我解决了这个问题,也许还没有意识到它是如何成为统计初学者的。

首先,建模数据中不应存在单个NA。有一个。之后,mcgv似乎开始运行,但是花了很长时间(四分之一小时),并且对我来说莫名其妙,只有当我将结数限制为k=50,且结果不佳(更少或更多,并且没有返回任何结果)时,结果),并警告您谨慎使用结果。 然后,我尝试删除offset=log(liczba_wyborcow),即抵消选民人数,并使每1000张无效投票数成为我的预测变量。

elections <-
 boroughs_shp %>%  
 left_join(elections_xls, by = "teryt") %>% na.omit() %>% 
 arrange(teryt) %>% 
 mutate(idx = row_number() %>% as.factor()) %>% 
 mutate(void_ratio=round(glosy_niewazne/liczba_wyborcow,3)*1000)

现在这很重要,为什么不尝试将gam公式中的family = betar()更改为poisson()-仍然不是一个好结果,然后更改为负二项式 {{1 }} 现在我的公式看起来像

family = nb()

现在看来速度非常快,并且可以返回没有警告或错误的有效结果。在具有4核Intel Core I7 6820HQ @ 2.70GHZ 16GB Win10的笔记本电脑上,现在需要1-2分钟来建立模型。

简而言之,我所做的更改是:删除单个N​​A,从公式中删除偏移并使用负二项式分布

这是我想要从左至右获得的实际无效票数,通过模型平滑的票数和表示差异的残差的结果。 mcgv代码让我做到了。

expected result