R中的空间面板回归:spgm出错

时间:2018-04-09 12:18:47

标签: r spatial panel-data

我对下面显示的空间回归代码有一个问题(代码示例)。运行回归后,我得到以下错误

Error in listw %*% as.matrix(ywithin) : 
  Cholmod error 'X and/or Y have wrong dimensions' at file ../MatrixOps/cholmod_sdmult.c, line 90

当我从回归中删除空间维度时,回归运行完美,所以我猜错误可能在空间权重矩阵中。有人可以帮我解决发生此错误的原因并推荐解决方案吗?

参考数据:

使用shapefile和数据链接到该文件夹​​: https://drive.google.com/drive/folders/1PFAhCpYnDCtV36DuTLh4V79Bs3RO5ESy?usp=sharing

代码示例(下载文件并演示错误)

requiredPackages <-
  c("rio", "plm", "splm", "tmaptools", "spdep", "fields", "readxl")

ipak <- function(pkg) {
  new.pkg <- pkg[!(pkg %in% installed.packages()[, "Package"])]
  if (length(new.pkg))
    install.packages(new.pkg, dependencies = TRUE)
  sapply(pkg, require, character.only = TRUE)
}

ipak(requiredPackages)

# URL's obtained from Google Shared Directory
pShareDataURL = "https://drive.google.com/open?id=1PjDlLiA99-3xuGPhPLltRg8uod6zPAKn"  ## data1.xlsx
sShareDataURL = "https://drive.google.com/open?id=1VJGL8aSJomvWCnw9FPEWTJsQ65StYdzW"  ## nuts2ashp
## strip "open?" and replace with us?export=download&
pdataURL <- gsub("open\\?", "uc\\?export=download\\&", pShareDataURL )
sdataURL <- gsub("open\\?", "uc\\?export=download\\&", sShareDataURL )

pdataDest = file.path("./data/data1.xlsx" )
sdataDest = file.path("./data/nuts2a.shp" )

if (!dir.exists("./data")) {
  dir.create(file.path("./data"), showWarnings = FALSE)
}

# Download files
download.file(pdataURL, destfile = pdataDest, method = "wget", mode = "wb")
download.file(sdataURL, destfile = sdataDest, method = "wget", mode = "wb")

pdata <- read_excel(pdataDest)
shape_nuts <- read_shape(sdataDest)

shape_nuts <- shape_nuts[order(shape_nuts@data$NUTS_ID), ]
shape_nuts2 <-
  shape_nuts[substr(shape_nuts@data$NUTS_ID, 1, 3) != "FR9" &
               shape_nuts@data$NUTS_ID != "UKI1"
             &
               shape_nuts@data$NUTS_ID != "EL21" &
               shape_nuts@data$NUTS_ID != "RO21", ]

#######computing the spatial weight matrix###########

coords2 <- coordinates(shape_nuts2)          # getting coordinates of the polygon centroids
dm <- rdist.earth(coords2, miles = FALSE)   # calculating distance between the polygon centroids
rownames(dm) <- shape_nuts2@data$NUTS_ID    # naming the rows
colnames(dm) <- shape_nuts2@data$NUTS_ID    # naming the columns

for (i in 1:dim(dm)[1]) {
  dm[i, i] = 0
}        # renders exactly zero all diagonal elements

dm1 <- ifelse(dm != 0, 1 / dm, dm) #inverting distance

# create a (normalized) listw object
dm1.lw <- mat2listw(dm1,
                    style = "W",
                    row.names = shape_nuts2@data$NUTS_ID)

#########regressions#######

spgr01 <- spgm(
  rgrowthpc ~ lrgdp0pc + lefpayr,
  data = pdata,
  listw = dm1.lw,
  model = "within",
  lag = TRUE,
  spatial.error = TRUE,
  endog =  ~ lefpayr,
  instruments =  ~ area_prop,
  method = "w2sls"
)

控制台输出:

> #########regressions#######
> 
> spgr01 <- spgm(
+   rgrowthpc ~ lrgdp0pc + lefpayr,
+   data = pdata,
+   listw = dm1.lw,
+   model = "within",
+   lag = TRUE,
+   spatial.error = TRUE,
+   endog =  ~ lefpayr,
+   instruments =  ~ area_prop,
+   method = "w2sls"
+ )
Error in listw %*% as.matrix(ywithin) : 
  Cholmod error 'X and/or Y have wrong dimensions' at file ../MatrixOps/cholmod_sdmult.c, line 90
>

1 个答案:

答案 0 :(得分:4)

在不知道你如何计算pdata的情况下,我们只能猜测。

如果您没有更改原始数据中的任何内容(如编辑@Technophobe01后的代码中所示),则会出现错误,因为在面板数据中,两个第一列应包含个人和时间索引,按此顺序。来自splm vignette

  

在splm中输入数据集确实有三种可能性:

     

•包含单个索引的data.frame(作为其第一个变量)   和时间指数(第二个变量)。索引参数应该是   保留其默认值NULL

     

•data.frame和由要用作的空间和变量名称组成的字符向量   时间)指数

     

•pdata.frame类的对象。

因此,我们可以将pdata加载为:

library(gsheet)

url <- 'drive.google.com/file/d/1PjDlLiA99-3xuGPhPLltRg8uod6zPAKn'
pdata <- gsheet2tbl(url)   

# reverse first and second column order
pdata <- pdata[, c(2:1,3:ncol(pdata))] 

head(pdata)
# A tibble: 6 x 19
#  nuts   year   d06   d13  eu10   d04   d09   eu2 eupigs  eu12 lefpayr lrgdp0pc rgrowthpc lpopgr  linvr wgipca area_prop laggdp0pc2 regid
#  <chr> <int> <int> <int> <int> <int> <int> <int>  <int> <int>   <dbl>    <dbl>     <dbl>  <dbl>  <dbl>  <dbl>     <dbl>      <dbl> <int>
#1 AT11   1996     0     0     0     0     0     0      0     0   -5.01     4.19    0.0316  -1.30 -0.598  -2.18     0.243       4.21     1
#2 AT11   1997     0     0     0     0     0     0      0     0   -5.06     4.21    0.0498  -1.31 -0.609  -2.03     0.243       4.18     1
#3 AT11   1998     0     0     0     0     0     0      0     0   -5.11     4.24    0.0554  -1.31 -0.622  -1.87     0.245       4.19     1
#4 AT11   1999     0     0     0     0     0     0      0     0   -5.14     4.25    0.0314  -1.32 -0.629   1.71     0.253       4.21     1
#5 AT11   2000     0     0     0     1     0     0      0     0   -5.23     4.27    0.0546  -1.40 -0.562  -1.94     0.253       4.24     1
#6 AT11   2001     0     0     0     1     0     0      0     0   -5.30     4.28    0.0139  -1.30 -0.554  -2.18     0.271       4.25     1

然后您可以运行模型(假设为listw = dm1.lw并删除endog = ~lefpayr,因为您无法定义模型中已有的其他内生变量):

spgr01 <- spgm(rgrowthpc ~ lrgdp0pc + lefpayr, 
             data = pdata, 
             listw = dm1.lw,
             model = "within",
             lag = TRUE, 
             spatial.error = TRUE, 
             instruments = ~area_prop,
             method = "w2sls" 
)

summary(spgr01)
#Spatial panel fixed effects GM model
# 
#
#Call:
#spgm(formula = rgrowthpc ~ lrgdp0pc + lefpayr, data = pdata, 
#    listw = dm1.lw, model = "within", lag = TRUE, spatial.error = TRUE, 
#    instruments = ~area_prop, method = "w2sls")
#
#Residuals:
#   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
# -1.087  -0.934  -0.908  -0.888  -0.861  -0.421 
#
#Estimated spatial coefficient, variance components and theta:
#            Estimate
#rho       0.84261722
#sigma^2_v 0.00084123
# 
#Spatial autoregressive coefficient:
#       Estimate Std. Error t-value Pr(>|t|)    
#lambda  1.84215    0.26141  7.0469 1.83e-12 ***
#
#Coefficients:
#            Estimate  Std. Error t-value  Pr(>|t|)    
#lrgdp0pc  0.20412808  0.01637557 12.4654 < 2.2e-16 ***
#lefpayr  -0.00080159  0.00022879 -3.5036 0.0004591 ***
#---
#Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1