掌握基本语法和操作,推荐国内的已经翻译的比如《R语言实战》《R语言编程艺术》,这个过程中最好结合一些小例子来做一些分析的东西。如果需要可视化的话,强烈不推荐学习R本身的作图系统,实在是太不友好了.....还是用ggplot2吧。
掌握了上面的,就可以深入一些了,如果是做数据分析和可视化,推荐《ggplot2:数据分析与图形艺术》,这个才是作图的神器啊.....如果是空间分析相关的,推荐《Applied Spatial Data Analysis with R》,这个如果可以的话看英文版,而且要有地学的一些知识背景,中文版翻译的太次了,尽量不要看。数据挖掘机器学习之类的,可以看看比如《数据挖掘与R语言》、《机器学习——实用案例解析》,不过我觉得这几本书没上面的那几本好,但是可以大概看看是咋回事,最好还是看看专门的相关书籍,熟悉各种算法和流程,到时候搜索R的package,照着文档和例子搞定,不是特别难。
地理加权回归(GWR)在R里面怎么实现?121 人关注0 条评论
写回答
查看全部 5 个回答
写回答
叶山Shan Ye
GIS/地质/人文地理/可持续发展
A2A 谢邀,
我和我认识的一些人,刚开始用R做空间分析的时候,也遇到过这个问题。R这种开源的东西,优点是各种包很丰富,缺点是有些包的说明写得很乱,地理加权回归(GWR)的R包其实功能很强大,但大部分说明都不大靠谱。
GWR在R里面可以用好几个不同的包来实现,其中步骤最简单的是spgwr。思路就两步:建立窗口、用窗口扫全局。这其实就是GWR本质上的两步。比如我要在全美国范围内统计某两个(或多个)变量之间的回归关系,我可以做一个全局回归(global regression),但因为这些变量在空间分布上或许会有异质性(heterogeneity),表现在统计结果上就是空间不稳定性(nonstationarity),因此只看全局的统计,可能看不出什么结果来。举个不完全恰当但是很容易领会精神的例子,你比如说,我要分析亚洲范围内,经济发展程度与牛肉销量之间的关系,经济越发达的地方,人们就越吃得起牛肉。可是等我统计到印度的时候,坏了,印度大部分人不吃牛肉,这不是经济状况导致的,这一下就影响了全局统计的参考价值,那怎么办呢?我们可以建立一个窗口(正规说法是带宽窗口,bandwidth window),每次只统计窗口范围内的经济与牛肉销量的关系,然后用这个窗口去扫过全局的范围。等统计到印度的时候,印度内部的各地和印度自己比,吃牛肉的人的比例就不会突然减少,这样就能减少这种空间不稳定性对全局统计的影响。
所以,第一步就是要建立这样一个『窗口』。当然了,首先要安装包,我们要用到的R包有:
library(spgwr)
library(rgdal)
library(sf)
library(spData)
library(sp)
library(lattice)
library(ggplot2)
library(ggthemes)
其中,spgwr是做GWR的包,rgdal是用来读取矢量要素的,sf,sp和spData都是用来处理矢量数据的,别的基本都是画图用。
以下默认你会R和GWR的基本操作。并且,以下只展现方法,不要纠结我的数据和结果,我随便找的数据,这个数据本身没有什么意义,所以做出的统计看起来很『壮观』。
我们先导入数据。这里我用的是美国本土48州各个县(county,也有翻译成郡的)的人口普查数据和农业数据,来源是ESRI Online数据库。为啥用这个数据呢?因为...我电脑里面就存了这么个可以用来做GWR的数据...
我们用rgdal读取数据,然后把它画出来看看
require(rgdal)
usa_agri <- readOGR(dsn = "~/Documents/Spatial", layer = "usa_counties")
plot(usa_agri)
会得到这个东西:
readOGR里面,dsn后面加储存shp的路径(加到文件夹为止),layer后面写shp的文件名(不加.shp)。不喜欢rgdal的同学可以不用,用maptools或者spData等别的处理shp的R包代替。不过如果用maptools,要注意处理一下参考系。
我们看一下这个shp里面的列联表都有什么:
可见,shp里面有3108个县的数据,数据有61种。然后再看data下面有什么:
总之就是各种人口普查的数据,后面截不完图,还有经济、房地产和农业之类的数据。那我们就随便选两个来当变量。我就随便挑了,因变量选AVESIZE12,即2012年各个县农场的平均占地面积。自变量选POP_SQMI,也就是人口密度(每平方英里的人口)。
现在正式建立窗口,调用的是spgwr里面的gwr.sel函数:
bw <- gwr.sel( AVE_SIZE12 ~ POP_SQMI, data = usa_agri, gweight = gwr.Gauss,
verbose = FALSE, method = "cv")
其中~前后分别是因变量和自变量。GWR里因变量只能有1个,但自变量可以选多个,如果需要多个自变量的话,就在代码POP_SQMI之后用+号连接就行。gweight是你的空间加权的函数(随空间距离增大而不断衰减的函数,衰减率由下面要提到的带宽控制),这里用的是比较常用的高斯函数,其余的还有gwr.bisquare等函数可以调用。verbose决定是否汇报制定窗口的过程。method是决定构建带宽窗口模型的方法,这里用的cv指的是cross validation,即交叉验证法,也是最常用的方法,简单说就是把数据分成不同的组,分别用不同的方法来做回归计算,计算完了之后记录下结果,然后打乱重新分组,再回归计算,再看结果,周而复始,最后看哪种计算方法的结果最靠谱,这种方法就是最优解。还有一种很常见的选择最佳拟合模型的方法是AIC optimisation法,把method后面的cv改成aic就可以用。具体AIC optimisation是什么:AIC(赤池信息准则)_百度百科。总之,空间加权函数和带宽窗口构建方法的选择是GWR里面十分重要的步骤。
以上便是固定带宽窗口的示意图。比如我在对佐治亚做GWR,这一轮的regression target是红色的这个县,根据做出来的窗口,圆圈以内的县都要被算为红色县的邻县,其权重根据高斯函数等空间权重函数来赋值,而圆圈以外的县,空间权重都赋为0。
不喜欢固定带宽窗口的同学也可以不用它,而是用符合Tobler地理学第一定律的非固定带宽邻域统计,操作方法是在gwr.sel里面加一个命令adapt = TRUE,这样的情况下,根据你设置的k邻居数,每一轮统计的时候,和本轮对象在k以内相邻的多边形的权重参数会被赋值为0到1之间的一个数,比如下图:
我在对佐治亚做GWR,这一轮的regression target是红色的这个县,那么图上标为1的县就是红色县的1阶邻县,标为2的是2阶(邻县的邻县),标为3的是3阶(邻县的邻县的邻县)。如果用非固定带宽邻域统计,k为3,那么1、2、3都被定义为红色县的邻县,它们的权重从3到1依次增加,会按比例被赋上0和1之间的值,而其它没有标注的县,权重为0。
下一步就是用前一步做出的窗口去扫过全局区域:
gwr_result <- gwr(AVE_SIZE12 ~ POP_SQMI, data = usa_agri, bandwidth = bw,
gweight = gwr.Gauss, hatmatrix = TRUE)
这一步如果数据量大,可能会要跑一阵,跑完之后我们看看结果里面有什么:
Call:
gwr(formula = AVE_SIZE12 ~ POP_SQMI, data = usa_agri, bandwidth = bw,
gweight = gwr.Gauss, hatmatrix = TRUE)
Kernel function: gwr.Gauss
Fixed bandwidth: 205880.3
Summary of GWR coefficient estimates at data points:
Min. 1st Qu. Median 3rd Qu.Max. Global
X.Intercept. 7.3883e+01 2.1081e+02 3.2802e+02 6.6691e+02 8.5705e+03 625.5656
POP_SQMI -8.0085e+01 -4.5983e-01 -1.4704e-01 -7.3703e-02 -2.1859e-03 -0.0426
Number of data points: 3108
Effective number of parameters (residual: 2traceS - traceS'S): 119.6193
Effective degrees of freedom (residual: 2traceS - traceS'S): 2988.381
Sigma (residual: 2traceS - traceS'S): 1048.78
Effective number of parameters (model: traceS): 84.90185
Effective degrees of freedom (model: traceS): 3023.098
Sigma (model: traceS): 1042.741
Sigma (ML): 1028.4
AICc (GWR p. 61, eq 2.33p. 96, eq. 4.21): 52109.55
AIC (GWR p. 96, eq. 4.22): 52017.7
Residual sum of squares: 3287040139
Quasi-global R2: 0.4829366
基本上你做GWR该需要的结果这里都有了。比如窗口大小(Fixed bandwidth)是205880.3,意思是前一步构建的带宽窗口是半径205.88千米的圆。Effective number of parameters显示的是你带宽窗口的大小合不合适。Sigma是残差的标准差,这个值要尽量小。Residual sum of squares(RSS)也是对拟合程度的一个评估值。最重要的是最后那个R2,越靠近1说明统计的拟合度越好。我这里面Sigma很大,R2也不是很大,因为我这里只是呈现方法,用的数据本来就是互不相干、没什么太大意义的,所以不用太纠结。如果你是真正的统计数据要来做GWR,就需要注意这些值了。
然后,我们就可以把每个县的R2画在地图上。首先,前面报告里的这些数据,比如R2,要先自己去生成的GWR结果里面去找,然后自己再算一下每个县的local R2,并把它们赋值到shp里面去:
1. 列出包所在库的路径.libPaths()
[1] "C:/Program Files/R/R-3.0.2/library"
2. 安装包,括号里面包的名称要加英文引号,在列出的CRAN镜像站点列表中选择一个进行下载,我一般选的是China(Hefei)
install.packages()
例如,install.packages("ggplot2")
3. 包的载入library()或require(),安装完包后,需要加载才能使用其中的函数,此时括号中不使用引号。两者的不同之处在于library()载入之后不返回任何信息,而require()载入后则会返回TRUE,因此require()适合用于程序的书写。
例如
library(ggplto2)
>require(foreign)
Loading required package: foreign
>is.logical(require(foreign))
[1] TRUE
4. 包的更新
update.packages()
5. 包的帮助信息 格式如下,可以查看包中的函数以及说明
help(package="ggplot2")
6. 查看本地的包
6.1 查看默认加载的包,忽略基本的包
getOption("defaultPackages")
>getOption("defaultPackages")
[1] "datasets" "utils" "grDevices" "graphics" "stats" "methods"
[7] "ggplot2"
6.2 查看当前已经加载过的包
(.packages())
[1] "ggplot2" "stats" "graphics" "grDevices" "utils" "datasets" "methods" "base"
6.3 要显示所有可用的包
(.packages(all.available=TRUE))
>(.packages(all.available=TRUE))
[1] "abind" "agricolae" "aplpack" "base" "bitops"
[6] "boot" "car" "caTools" "class" "cluster"
[11] "codetools" "colorRamps" "colorspace" "compiler" "datasets"
[16] "Defaults" "devtools" "dichromat" "digest" "doBy"
[21] "e1071" "effects" "ellipse" "evaluate" "foreign"
[26] "formatR" "Formula" "gdata" "ggplot2" "ggthemes"
[31] "gmodels" "gplots" "graphics" "grDevices" "grid"
[36] "gtable" "gtools" "highr" "Hmisc" "httr"
[41] "KernSmooth" "knitr" "labeling" "lattice" "latticeExtra"
[46] "leaps" "lme4" "lmtest" "LSD" "manipulate"
[51] "markdown" "MASS" "Matrix" "matrixcalc" "memoise"
[56] "methods" "mgcv" "minqa" "multcomp" "munsell"
[61] "mvtnorm" "nlme" "nnet" "nortest" "parallel"
[66] "pixmap" "plyr" "proto" "psych" "quantmod"
[71] "Rcmdr" "RColorBrewer" "Rcpp" "RcppEigen" "RCurl"
[76] "relimp" "reshape2" "rgl" "rJava" "RODBC"
[81] "rpart" "rstudio" "samplesize" "sandwich" "scales"
[86] "schoolmath" "sciplot" "sem" "spatial" "splines"
[91] "stats" "stats4" "stringr" "survival" "tcltk"
[96] "tcltk2" "TH.data" "tools" "TTR" "utils"
[101] "VennDiagram" "whisker" "XLConnect" "xts" "zoo"
7. 卸载包detach(),这是library()的反向操作,此操作主要是为了避免某些包中的函数名称相同,造成冲突,注意与library()的参数不同,detach()参数为detach(package:包的名称),library(包的名称)。
例如
>library(ggplot2) #加载包
>(.packages()) #列出当前已经加载的包
[1] "ggplot2" "stats" "graphics" "grDevices" "utils" "datasets"
[7] "methods" "base"
>detach(package:ggplot2) # 卸载ggplot2包
>(.packages()) #列出当前已经加载的包
[1] "stats" "graphics" "grDevices" "utils" "datasets" "methods"
[7] "base"
8. 自定义启动时候的加载包
如果需要长期使用某个包的话,每次开启都需要输入library(),比较麻烦,因此可以让R启动时自动加载某些包。在R的安装目录/etc/Rprofile.site加入下载语句:
例如让R启动时自动加载ggplot2包
local({old <- getOption("defaultPackages")
options(defaultPackages = c(old, "ggplot2"))})
9. 在文章中引用R软件包,例如引用ggplot2包:
citation(package="ggplot2")
To cite ggplot2 in publications, please use:
H. Wickham. ggplot2: elegant graphics for data analysis. Springer New
York, 2009.
A BibTeX entry for LaTeX users is
@Book{,
author = {Hadley Wickham},
title = {ggplot2: elegant graphics for data analysis},
publisher = {Springer New York},
year = {2009},
isbn = {978-0-387-98140-6},
url = {http://had.co.nz/ggplot2/book},
}