在智慧水务建设中,DMA(独立计量区域)通过安装边界流量计把城市供水管网划分为若干封闭区块,从而实现水量平衡分析与漏损管控。基于R语言的方案能够让中小型水司在不采购昂贵专有平台的前提下,利用开源生态完成从数据采集、实时监测到漏损定位的闭环。R本身具备强大的时间序列处理、统计建模与网络分析能力,配合数据库与消息队列即可搭建轻量级监测后台。

DMA分区计量的数据特征与R数据接入
DMA区块通常会在入口总管、关键节点以及末端布置电磁流量计和压力变送器,采样周期多为十五分钟或一小时。这些数据表现出明显的双周期特征:一天内的用水高峰与夜间最小流量,以及工作日与周末的差异。同时,压力变化会直接影响漏损出流量,因此单纯看水量差容易误报。我们在R中可以使用DBI包连接时序数据库,用dbGetQuery拉取指定DMA编号的最近二十四小时记录。
为了提高后续分析效率,应当先把原始数据整理为xts或data.table对象,并按时间戳对齐。下面示例展示如何从PostgreSQL读取数据并做初步清洗,包括剔除通信中断造成的空值以及将压力单位统一为千帕。
library(DBI)
library(RPostgres)
library(xts)
con <- dbConnect(RPostgres::Postgres(),
host = '127.0.0.1',
dbname = 'water_dma',
user = 'reader',
password = 'secret')
sql <- "SELECT ts, inflow, pressure FROM dma_flow
WHERE dma_id = 'DMA_032'
AND ts > now() - interval '24 hours'"
raw <- dbGetQuery(con, sql)
dbDisconnect(con)
raw <- raw[!is.na(raw$inflow), ]
flow_xts <- xts(raw$inflow, order.by = raw$ts)
pres_xts <- xts(raw$pressure, order.by = raw$ts)
colnames(flow_xts) <- 'inflow'
colnames(pres_xts) <- 'pressure'
完成接入后,建议对每个DMA计算基线夜间流量(通常为凌晨两点到四点的最小值滑动均值)。R的rollapply函数可以方便实现该逻辑。只有将实时值持续与该基线对比,才能识别出异常增量,这是漏损实时监测的第一道闸门。
基于时间序列分解的漏损实时监测模型
漏损信号往往隐藏在总用水量的随机波动中。如果直接设固定阈值,夏季用水量大时会产生大量误报,冬季又可能漏报。更稳妥的做法是利用R的forecast包对历史同期数据做STL分解,把趋势、周期与残差分开,残差部分即代表不可解释的流量突变。当残差连续超过三倍标准差且压力同步下降,系统就触发疑似漏损事件。
以下代码演示如何用stl函数分解 hourly 流量,并提取残差上限作为动态阈值。实践中可将该过程封装为定时任务,每新到一个数据点就滚动更新模型,从而实现近实时监测而不是隔夜批处理。
library(forecast)
# 假设 flow_ts 为 ts 对象,频率 24(按小时)
decomp <- stl(flow_ts, s.window = 'periodic', t.window = 24)
resid <- decomp$time.series[, 'remainder']
dyn_threshold <- mean(resid) + 3 * sd(resid)
latest_resid <- resid[length(resid)]
if (latest_resid > dyn_threshold) {
alarm <- TRUE
} else {
alarm <- FALSE
}
这种监测方式相比传统水平衡报表的优势在于:它能自适应季节与天气变化,且残差报警可关联到具体小时,便于值班人员快速确认。我们还可以把多个DMA的报警通过shiny仪表盘集中展示,用颜色区分严重程度,避免信息淹没。
需要指出,监测模型本身不能给出漏点位置,它只回答“哪里可能正在漏”。若要进一步定位,必须引入管网拓扑与压力空间分布,这就进入了下一节讨论的定位算法。
结合图论与压力反距离加权的漏损定位
DMA内部的管网可以抽象为无向图,节点是阀门、水表与压力点,边是管段。R的igraph包能够加载该图并计算任意两节点间的最短路径距离。当某个压力监测点观察到压力骤降,而相邻点降幅较小,漏点更可能靠近前者。我们使用反距离加权(IDW)把离散压力变化插值到图上每个节点,获得一个“压力异常场”。
具体实施时,先读取管网GeoJSON或邻接表构建图对象,再把实时压力变化量作为权重附加到对应顶点。运行下面脚本可得到各节点异常评分,评分最高的子区域即为推荐排查范围。该方法计算轻量,在普通服务器上可支撑数百个DMA并行定位。
library(igraph)
# g 为已构建的 igraph 对象,pres_drop 为命名向量:节点名->压力下降值
nodes <- V(g)$name
score <- numeric(length(nodes))
names(score) <- nodes
for (n in nodes) {
d <- distances(g, v = n, to = V(g)$name)
w <- ifelse(d == 0, 0.01, 1 / (d ^ 2))
score[n] <- sum(pres_drop * w, na.rm = TRUE)
}
top_node <- names(sort(score, decreasing = TRUE))[1]
cat('疑似漏点最近节点:', top_node, 'n')
相比单纯依靠经验派工,图论加IDW定位能把排查面积从整个DMA缩小到一两栋楼或一段支管。如果水司还在关键管段部署了噪声记录仪,可把噪声相关结果作为额外权重并入上述评分,精度会进一步提升。整个流程从数据接入、监测到定位均可用R脚本串接,形成可审计、低成本的智慧水务网络核心。