我有一张可用的采样站表,其中包含唯一标识符GRID_ID
以及每个站的纬度和经度(和UTM)。我想随机选择这些站的子集,我可以使用sample()
轻松完成。
但是,为了最大限度地提高效率,我还想通过指定任何随机选择的采样站必须在至少x
个其他站的y
距离内来采用一些聚类。
基本原理是,长途旅行以对一组y
站点进行采样是有意义的,但是长途旅行到样本< y
站是没有意义的。
这有意义吗?有没有一种直接的方法来处理R?
答案 0 :(得分:0)
这个怎么样:
# some random data
set.seed(1)
df <- data.frame(x=runif(10), y=runif(10))
# e.g. select obs that have >= 1 neighbour closer than .3 (euclidean)
mat <- as.matrix(dist(df))
sel <- rowSums(mat < .3) >= 2
plot(y~x, df, col = sel + 1L) # viz
# e.g. select obs that have >= 2 neighbours closer than 40000 (great circle/lon,lat)
library(geosphere)
mat <- distm(as.matrix(df))
sel <- rowSums(mat < 40000) >= 3
plot(y~x, df, col = sel + 1L) # viz
# Take 2 random obs from those who meet the criteria
df[sample(which(sel), size = 2), ]
好的,计算~31000个数据点之间的距离矩阵可能会阻塞普通的计算机。另一种方法可能是使用基于密度的聚类,如DBSCAN。它看起来像这样:
# load your data
set.seed(1)
download.file("https://dl.dropboxusercontent.com/u/17339799/MHI_BF_Survey_Domain_PSU.txt", tf <- tempfile(fileext = ".csv"))
fullds <- read.csv(tf)
df <- fullds[, c("lon_deg", "lat_deg")]
library(dbscan)
kNNdistplot(as.matrix(df), k=4) # determine eps value...
res <- dbscan(as.matrix(df), eps = .005, minPts = 4, borderPoints=F)
# DBSCAN clustering for 31083 objects.
# Parameters: eps = 0.005, minPts = 4
# The clustering contains 134 cluster(s).
# Available fields: cluster, eps, minPts
noise <- res$cluster == 0
sum(noise)
# [1] 2499
# interactive plot with zoom
# (draw rectangle with right mouse,
# CTRL to reset)
library(iplot)
iplot(df$lon_deg, df$lat_deg, col=noise + 1L)
您可能需要调整它以满足您的需求。但是
idx <- sample(which(!noise), 250)
fullds[idx, ]
然后会给你样品。