R语言空间插值的几种方法及案例应用


640?wx_fmt=gif


作者简介

勾蒙蒙,R语言资深爱好者。

个人公众号: R语言及生态系统服务。


前文传送门:

脏数据-数据量纲差异

地形图绘制


##加载程序包

library(raster)

library(sp)

library(rgdal)

library(gstat)

library(raster)

library(maptools)

##设置工作空间

setwd("C:/Users/lx/Desktop/sun")

数据为环京津冀地区153个站点2002年7月降雨数据

##读取数据

Data<-na.omit(read.csv("Data.csv",header=T))

head(Data)

 Month  Plot Year  rain        X        Y

1     7 54365 2002 139.8 125.3500 41.28333

2     7 54259 2002 197.5 124.9167 42.01000

3     7 54493 2002 317.6 124.7833 40.71667

4     7 54497 2002 179.4 124.3333 40.05000

5     7 54351 2002 159.8 124.0833 41.91667

6     7 54254 2002  88.90 124.0500 42.53333

制图显示数据

plot(sort(Data$rain), ylab=" 年降雨量(mm)", las=1, xlab='站点')


640?wx_fmt=jpeg 

##导入京津冀地区矢量地图

bound<-readOGR("bound.shp")

plot(bound,col="grey")

640?wx_fmt=jpeg

##设定降雨数据的投影为WGS84

dsp <- SpatialPoints(Data[,5:6], proj4string=CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))

dsp <- SpatialPointsDataFrame(dsp,Data)

展示一个直观的地图

cuts<-c(0,30,50,100,150,300)#设置间距

blues <- colorRampPalette(c("red","blue"))(5)#设置颜色梯度,即渐变色。c("red","blue")(5)代表颜色从黄色渐变到橘色,再渐变到蓝色,再到深蓝色,5则代表长度为5。例子:plot(20:1, bg = blues[rank(5:1)], cex = 2, pch = 22)

pols <- list("sp.polygons",bound, fill = "lightgray")#构建京津冀的SpatialPolygons对象

spplot(dsp,"rain", cuts=cuts, col.regions=blues, sp.layout=pols, pch=20, cex=2)

640?wx_fmt=jpeg

将经纬度转成平面坐标,使插值结果与数据保持一致,这里用到的坐标系也是WGS84,+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0

WGS84<- CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0")#设置参考系WGS84

dsp1<-spTransform(dsp,WGS84)#将经纬度转成平面坐标,使用WGS参考系

bound1<-spTransform(bound,WGS84)

 使用邻域多边形插值

library(dismo)

v <- voronoi(dsp1)

plot(v)

640?wx_fmt=jpeg

这个图看起来怪怪的,接下来,我们将其范围限定在京津冀地区

bound2<-aggregate(bound1)#聚合,降低分辨率

v1<-intersect(v,bound2)#将两个图层相交

spplot(v1, "rain", col.regions=rev(get_col_regions()))#绘制多边形图

640?wx_fmt=jpeg

这个图看起来则要舒适的多,但其输出的结果是多边形,接下来用”rasterize”将结果栅格化,为详细介绍shape格式转栅格的过程,这里增加一个小专题:Shape转栅格

在shape转栅格之前,首先需要建议一个新的空白的栅格,并指定控制栅格分辨率的行列,用extent制定空间范围

blank_raster<-raster(nrow=100,ncol=100,extent(bound))

接下来给栅格赋值

values(blank_raster)<-1

plot(blank_raster)

 640?wx_fmt=jpeg

640?wx_fmt=jpeg

因为给栅格的赋值都为1,因此上图显示的也只有一个颜色,你也可以给栅格赋值多个,即nrow*ncol

values(blank_raster)<-1:(100*100)

plot(blank_raster,col=rainbow(100))

下图则看起来要好的多了,下面将用到rasterize进行正式转换了,这里需要注意的是栅格是有分辨率的,因此上面设置的100*100的分辨率有可能不一定合适,我们用循环看一下

layout(matrix(1:4, ncol=2, byrow=TRUE))

res<-c(20,100,500,1000)

for(r in res){

blank_raster<-raster(nrow=r,ncol=r,extent(bound))

values(blank_raster)<-1

bound_raster<-rasterize(bound,blank_raster)

bound_raster[!(is.na(bound_raster))] <- 1

plot(bound_raster,main=paste("Res: ",r,"*",r))

plot(bound,add=T)

}

640?wx_fmt=jpeg毫无疑问,1000*1000的分辨率吻合效果要更好,但也不一定越高越好,会影响处理速度,这里我们选择1000*1000的分辨率

言归正传,将结果栅格化:

vr <- rasterize(v1,bound_raster,"rain")

plot(vr)

640?wx_fmt=jpeg

使用最近邻点插值

gs<-gstat(formula=rain~1,location=dsp1,nmax=5,set=list(idp=0))

nn<-interpolate(bound_raster,gs)

nnmask<-mask(nn,vr)##掩膜提取

plot(nnmask)


640?wx_fmt=jpeg

反距离加权插值

gs <- gstat(formula=rain~1, locations=dsp1)

idw <- interpolate(bound_raster, gs)

idwmask<-mask(idw,vr)

plot(idwmask)

640?wx_fmt=jpeg

普通克里金插值

克里金法是通过一组具有 z 值的分散点生成估计表面的高级地统计过程。与插值工具集中的其他插值方法不同,选择用于生成输出表面的最佳估算方法之前,有效使用克里金法工具涉及 z 值表示的现象的空间行为的交互研究。

求变异函数,首先绘制半变异图

v<- variogram(log(rain) ~ 1, data =dsp)

plot(v,plot.number=T)

640?wx_fmt=jpeg

根据半变异图可知,已知点的自相关关系semivariance随着距离distance的增加而增加,通过其分布,可初步确定用线性函数来拟合:确定哪些函数可以用show.vgms()实现。

640?wx_fmt=jpeg

v.fit<-fit.variogram(v,model=vgm(1,"Lin",0))

plot(v,v.fit)


640?wx_fmt=jpeg

Grid<-as(bound_raster,"SpatialGridDataFrame")#首先现将边界栅格转成空间网格

kri<-krige(formula=rain~1,model=v.fit,locations=dsp,newdata=Grid,nmax=12, nmin=10)#location为已知点的坐标;newdata为需要插值的点的位置;nmax和nmin分别代表最多和最少搜索点的个数

spplot(kri["var1.pred"])

640?wx_fmt=jpeg

泛克里金插值

用泛克里金法需谨慎,因其假定数据中存在覆盖趋势,应该仅在了解数据中存在某种趋势并能够提供科学判断描述泛克里金法时,才可使用该方法

v<- variogram(log(rain) ~ X+Y, data =dsp)

plot(v,plot.number=T)

v.fit<-fit.variogram(v,model=vgm(1,"Lin",0))

plot(v,v.fit)

uk <- krige(ANN_PREC ~ X + Y, dsp, Grid, v.fit)

Grid<-as(bound_raster,"SpatialGridDataFrame")

kri<-krige(formula=rain~1,model=v.fit,locations=dsp,newdata=Grid,nmax=12, nmin=10)

spplot(kri["var1.pred"])


640?wx_fmt=jpeg

薄盘样条函数

install.packages("fields")

library(fields)

m <- Tps(coordinates(dsp), dsp$rain)

tps <- interpolate(bound_raster, m)

tps <- mask(tps, bound_raster)

plot(tps)

640?wx_fmt=jpeg

 往期精彩内容整理合集 

2017年R语言发展报告(国内)

R语言中文社区历史文章整理(作者篇)

R语言中文社区历史文章整理(类型篇)

640?wx_fmt=jpeg

公众号后台回复关键字即可学习

回复 R                  R语言快速入门及数据挖掘 
回复 Kaggle案例  Kaggle十大案例精讲(连载中)
回复 文本挖掘      手把手教你做文本挖掘
回复 可视化          R语言可视化在商务场景中的应用 
回复 大数据         大数据系列免费视频教程 
回复 量化投资      张丹教你如何用R语言量化投资 
回复 用户画像      京东大数据,揭秘用户画像
回复 数据挖掘     常用数据挖掘算法原理解释与应用
回复 机器学习     人工智能系列之机器学习与实践
回复 爬虫            R语言爬虫实战案例分享

#include <iostream> #include <cmath> #include <fstream> using namespace std; class scyt { float *x,*y,*d,*h,*u,*q,*a,*b,*c,*l,*r,*o,*M; int m; float y0,y3; public: scyt(); void qiudao(); void zgf(); void qiujie(); ~scyt(); }; void main() { scyt hello; hello.qiudao(); hello.zgf(); hello.qiujie(); } scyt::scyt() { ifstream fin("三次样条插值.txt"); for(float j;fin>>j;) { m=int(j); break; } x=new float[m]; y=new float[m]; d=new float[m]; h=new float[m-1]; u=new float[m-2]; q=new float[m-2]; a=new float[m-1]; b=new float[m]; c=new float[m-1]; l=new float[m]; r=new float[m-1];//此处的r为追赶法中的u; o=new float[m];//此处o为追赶法中的y M=new float[m];//此处M为追赶法中的x; int jishu=0; for(j;fin>>j;) { if(jishu<=m-1) x[jishu]=j; if(jishu>m-1&&jishu;<2*m) { y[jishu-m]=j; } if(jishu==2*m) { y0=j; } if(jishu==2*m+1) { y3=j; } jishu++; } fin.close(); } void scyt::qiudao() { for(int i=0;i<m-1;i++) { h[i]=x[i+1]-x[i]; } for(i=0;i<m-2;i++) { u[i]=h[i] / (h[i] + h[i+1]); } for(i=0;i<m-2;i++) { q[i]=1-u[i]; } d[0]=6/h[0]*((y[1]-y[0])/h[0]-y0); for(i=1;i<m-1;i++) { d[i]=6/(h[i-1]+h[i])*((y[i+1]-y[i])/h[i]-((y[i]-y[i-1])/h[i-1])); } d[m-1]=6/h[m-2]*(y3-(y[m-1]-y[m-2])/h[m-2]); } void scyt::zgf() { u[m-2]=1; for(int i=0;i<m;i++) { b[i]=2; } c[0]=1; for(i=1;i<m-1;i++) { c[i]=q[i-1]; } //........................................ l[0]=b[0]; for(i=0;i<m-1;i++) { r[i]=c[i] / l[i]; l[i+1]=b[i+1] - (u[i] * r[i]); } o[0]=d[0] / l[0]; for(i=1;i<m;i++) { o[i]=(d[i]-u[i-1]*o[i-1]) / l[i]; } M[m-1]=o[m-1]; for(i=m-2;i>=0;i--) { M[i]=o[i]-r[i] * M[i+1]; } cout<<m<<"个点的导数值分别是:"<<endl; for(i=0;i<m;i++) { cout<<"M"<<i+1<<"="; cout<<M[i]<<endl; } //M的值求出。。。。。。追赶法调用完毕 } void scyt::qiujie() { float S; for(;;) { float f; cout<<"请输入待求x的值(输入1000)时退出:"; cin>>f; if(f==1000) break; for(int i=0;i<m;i++) { if(f>x[i]&&f<x[i+1]) { S=pow((x[i+1]-f),3)*M[i]/(6*h[i]) + pow(f-x[i],3)*M[i+1]/(6*h[i]) + (x[i+1]-f)*(y[i]-h[i]*h[i]*M[i]/6)/h[i] + (f-x[i])*(y[i+1]-h[i]*h[i]*M[i+1]/6)/h[i]; cout<<"S["<<f<<"]="<<S<<endl; } } } } scyt::~scyt() { delete []x,y,d,h,u,q,a,b,c,l,r,o,M; }
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值