使用R

时间:2016-01-12 19:57:23

标签: r distance igraph raster

我一直试图找到一个快速功能来同时使用R来测量栅格中几个贴片之间的距离。特别是,我想测量到每个方向上最近贴片的距离(不仅是最近的贴片) 。由于识别每个方向上最接近的一个可能很耗时,因此每个补丁的距离也可以解决问题。

首先我使用gDistance,但结果不直观(参见下面的示例)。特别是,很难将电导与光栅中方块之间的实际距离联系起来。

然后我尝试使用每个补丁迭代的光栅包,测量从那里到补丁的每个像素的距离(使用函数距离),然后寻找到每个其他补丁的最小距离。它有效,但它非常耗时。这也是非常低效的,因为我测量每个距离两次,因为我也测量不需要的距离(如果从补丁A到补丁C的唯一方法穿过补丁B,我不需要补丁A和C之间的距离。 以下是我使用的代码......

感谢您的任何建议......

Carlos Alberto

gdistance代码

library(gdistance)
library(raster)
# setting the patches
mF <- raster(nrows=10, ncols=20)
mF[] <- 0; mF[4:8,3] <- 2; mF[9,14:18] <- 3; mF[3,9:12] <- 1
# and the cost function
mg <- mF <= 0
# and the transition matrix
tr1 <- transition(1/mg, transitionFunction=mean, directions=16)
tr1C <- geoCorrection(tr1, type="c")
# getting coordinates of sampling points
dF1 <- as.data.frame(mF,xy=T, na.rm=T)
dF2 <- dF1[!duplicated(dF1[,3]),]
dF3 <- as.matrix(dF2[,1:2])
rownames(dF3) <- dF2[,3]
# and measuring the cost distance
cbind(dF3, as.matrix(costDistance(tr1C,dF3)))

给这个:

     x   y       0       1         2         3
0 -171  81       0 2192567 2079216.3 2705664.0
1  -27  45 2192567       0 2727389.7 3353837.4
2 -135  27 2079216 2727390       0.0  626447.7
3   63 -63 2705664 3353837  626447.7       0.0

主要关注点:1。价值意味着什么?如何将它们与km联系起来? 2.为什么到0级的距离随纬度增加?如果像素的面积减少到更接近极点,则每个绘图外部的距离也应该减小。

光栅代码

region <- (mF > 0) + 0 # the landscape map.

# this is just to reduce the creation/destruction of the variables

patch <- region
biome <- region
biomes <- unique(region)
areas <- area(region)

map.distances <-function (i) {
  dA <- data.frame(biome = integer(0), 
                   patch = integer(0), 
                   area = numeric(0))
  dD <- data.frame(biome = integer(0), 
                   from = integer(0), 
                   to = integer(0), 
                   dist = numeric(0))
  biome[] <- NA_integer_

  # creating the patches

  biome[region == i] <- i
  biomeC <- clump(biome, directions=8)
  dA <- rbind(dA, cbind(biome = i, 
              zonal(areas, biomeC, 'sum')))
  patches <- as.integer(unique(biomeC))

  # in each patch...

  for (j in patches[-1]) {
    patch[] <- NA_integer_
    patch[biomeC == j] <- 1L
    # get the distances from the patch
    dists <- distance(patch)
    d <- zonal(dists, biomeC, "min")
    f <- j > d[,1]
    # and combine the info
    dD <- rbind(dD, data.frame(from = j, 
                   to = d[f,1], 
                   dist = d[f,2], biome = i))
  }
  return(list(edges=dD, vertices=dA))
}


# applying to the same map as before gives:

mpd <- map.distances(i=1)

rownames(mpd$edges) <- NULL
mpd$edges
  from to     dist biome
1    2  1  9210860     1
2    3  1 12438366     1
3    3  2  5671413     1

看到距离不是线性相关的。

1 个答案:

答案 0 :(得分:1)

这是另一种方法,raster可能更有效(但对于真实(大)数据集可能有问题)。我使用更简单的(平面)栅格来更好地理解结果:

library(raster)
# setting the patches
mF <- raster(nrows=10, ncols=20, xmn=0, xmx=20, ymn=0, ymx=10, crs='+proj=utm +zone=10 +datum=WGS84')
mF[] <- 0; mF[4:8,3] <- 2; mF[9,14:18] <- 3; mF[3,9:12] <- 1

dF <- as.data.frame(mF, xy=TRUE, na.rm=TRUE)
dF <- dF[dF[,3] > 0,]
pd <- pointDistance(dF[,1:2], lonlat=FALSE)
pd <- as.matrix(as.dist(pd))
diag(pd) <- NA
a <- aggregate(pd, dF[,3,drop=FALSE], min, na.rm=TRUE)
a <- t(a[,-1])
a <- aggregate(a, dF[,3,drop=FALSE], min, na.rm=TRUE)[, -1]
diag(a) <- 0

a
#        V1        V2        V3
#1 0.000000  6.082763  6.324555
#2 6.082763  0.000000 11.045361
#3 6.324555 11.045361  0.000000

这里有gdistance:

# I think the cost is the same everywhere:
mg <- setValues(mF, 1)

# and the transition matrix
tr1 <- transition(1/mg, transitionFunction=mean, directions=16)
tr1C <- geoCorrection(tr1, type="c")
cd <- as.matrix(costDistance(tr1C, as.matrix(dF[,1:2])))
b <- aggregate(cd, dF[,3,drop=FALSE], min, na.rm=TRUE)
b <- t(b[,-1])
b <- aggregate(b, dF[,3,drop=FALSE], min, na.rm=TRUE)[, -1]
diag(b) <- 0
b
#        V1        V2        V3
#1 0.000000  6.236068  6.472136
#2 6.236068  0.000000 11.236068
#3 6.472136 11.236068  0.000000

您可以仅使用修补程序的边界来减少要使用的点数。考虑:

mF[] <- NA; mF[4:8,3] <- 2; mF[9,14:18] <- 3; mF[3,9:12] <- 1
mF[1:5, 1:5] = 2
plot(boundaries(mF, type='inner'))

您还可以先创建多边形

mF[] <- NA; mF[4:8,3] <- 2; mF[9,14:18] <- 3; mF[3,9:12] <- 1
p <- rasterToPolygons(mF, dissolve=TRUE)
gDistance(p, byid=T)

#        1  2        3
#1 0.00000  5  5.09902
#2 5.00000  0 10.00000
#3 5.09902 10  0.00000