假设输入参数是间隔
$step
。第一个区间的左边界为零。然后对于
ex.expr
我们可以计算它的间隔:
floor(ex.expr / $step)
因此,我们需要:
-
浏览所有关系
-
计算它们所属的时间间隔
-
计算每个间隔的数量
-
按间隔顺序分离
-
并返回结果(并计算区间边界)
查询的概念(
$步
是输入参数):
MATCH (c:Cell)-[ex:EXPRESSES]->(g:Gene {geneName:"Ifnar1"})
WITH floor(ex.expr / $step) AS intervalIndex,
count(c) AS cellCount
ORDER BY intervalIndex ASC
RETURN intervalIndex,
cellCount
如果我们不仅要返回区间数,还要返回其边界,该怎么办
MATCH (c:Cell)-[ex:EXPRESSES]->(g:Gene {geneName:"Ifnar1"})
WITH floor(ex.expr / $step) AS intervalIndex,
count(c) AS cellCount
ORDER BY intervalIndex ASC
WITH intervalIndex, cellCount,
$step * intervalIndex AS leftBoundary,
$step * (intervalIndex + 1) AS rightBoundary
RETURN intervalIndex,
[leftBoundary, rightBoundary] AS intervalBoundaries,
cellCount
对于某些步骤值,返回的间隔值将不准确,例如在步骤0.2,intervalIndex为2-
[0.4, 0.6000000000000001]
而不是
[0.4, 0.6]
。因此,根据小数点后一步中的位数,我们需要计算计算精度因数,并四舍五入到所需位数(基于Mark Needham post
http://markhneedham.com/blog/2014/05/25/neo4j-cypher-rounding-a-float-value-to-decimal-places/
):
WITH toInteger(split(toString($step - floor($step)), '.')[1]) AS precision
WITH CASE WHEN precision IS NULL THEN 0 ELSE precision END AS precision
WITH 10 ^ precision AS factor
MATCH (c:Cell)-[ex:EXPRESSES]->(g:Gene {geneName:"Ifnar1"})
WITH factor,
floor(ex.expr / $step) AS intervalIndex,
count(c) AS cellCount
ORDER BY intervalIndex ASC
WITH intervalIndex, cellCount,
round(factor * $step * intervalIndex) / factor AS leftBoundary,
round(factor * $step * (intervalIndex + 1)) / factor AS rightBoundary
RETURN intervalIndex,
[leftBoundary, rightBoundary] AS intervalBoundaries,
cellCount