spatial panel regression in R: Error with spgm

2019-08-24 04:18发布

I have one problem with the spatial regression code shown below (Code Example). After I run the regression I get the following error

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

When I remove the spatial dimension from the regression, the regression runs perfectly, so I guess the error might be in the spatial weight matrix. Could someone please help me address why this error occurs and recommend a solution?

Reference Data:

Link to the folder with the shapefile and the data: https://drive.google.com/drive/folders/1PFAhCpYnDCtV36DuTLh4V79Bs3RO5ESy?usp=sharing

Code Example (Downloads files and Demonstrates Error)

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"
)

Console Output:

> #########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条回答
一夜七次
2楼-- · 2019-08-24 04:51

Without knowing how you have computed pdata, we can only guess.

If you did not change anything from the raw data (as shown now in your code after the edit of @Technophobe01), there will be an error because in panel data, the two first columns should contain the individual and the time indexes, in that order. From the splm vignette:

Three possibilities are indeed available to input a data set in splm:

• a data.frame containing the individual index (as its first variable) and the time index (second variable). The index argument should be left to its default value of NULL

• a data.frame and a character vector composed of the names of the variables to be used as (space and time) indices

• an object of the class pdata.frame.

Therefore, we can load pdata as:

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

Then you can run your model (assuming listw = dm1.lw and removing endog = ~lefpayr as you cannot define an additional endogenous variable that is already in your model):

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
查看更多
登录 后发表回答