理解Breakpoint函数:R语言自定义断点函数内部for循环运行逻辑
R函数
my_breaks运行原理详解 整体功能说明
这个函数的作用是为数值向量生成近似等观测数的区间断点:
- 无重复值(ties)时,除了末尾区间,每个区间刚好包含h个观测
- 有重复值时,不会把相同值拆分到不同区间,因此部分区间观测数会大于h
逐行逻辑拆解
完整函数代码如下:
my_breaks <-function(x, h = 5) { x <-sort(x) breaks <- xb <- x[1] k <- 1 for(i in seq_along(x)[-1]) { if(k<h) { k <- k+1 } else{ if(xb<x[i-1]&&x[i-1]<x[i]) { xb <- x[i-1] breaks <-c(breaks, xb) k <- 1 } } } # 原函数漏了返回值,常规使用需补return(c(breaks, max(x))) }
各部分含义:
x <- sort(x):先对输入向量从小到大排序,保证断点按数值顺序生成breaks <- xb <- x[1]:初始化断点向量breaks,第一个断点为排序后向量的最小值;xb用于存储上一个生成的断点值,初始和第一个断点一致k <- 1:k是当前区间的观测计数器,初始已经计入第一个观测值,因此为1for(i in seq_along(x)[-1]):遍历排序后向量的下标,从第二个元素的下标2开始,到最后一个元素的下标结束,i代表当前正在处理的元素的下标
核心疑问解答
1. 循环变量i和k的关联逻辑
你疑惑的代码片段:
for(i in seq_along(x)[-1]) {if(k<h) {k <- k+1}
虽然没有直接写k和i的算术关联,但二者是通过循环迭代绑定的:每轮循环对应处理1个新的观测值,只要当前区间攒的观测数还没到h,每多处理1个观测(i往前走1步),计数器k就加1,相当于把当前第i个观测计入当前区间。
举个h=5的例子,初始k=1:
| 循环次数 | i的值 | 分支判断 | k的变化 | 含义 |
|---|---|---|---|---|
| 1 | 2 | k=1<5 | k=2 | 第2个观测计入当前区间 |
| 2 | 3 | k=2<5 | k=3 | 第3个观测计入当前区间 |
| 3 | 4 | k=3<5 | k=4 | 第4个观测计入当前区间 |
| 4 | 5 | k=4<5 | k=5 | 第5个观测计入当前区间 |
| 5 | 6 | k=5不小于5 | 进入else分支 | 当前区间已经攒够5个观测,准备切断点 |
2. 按h间隔筛选断点的逻辑
当k达到h进入else分支后,会执行断点判断:
if(xb<x[i-1]&&x[i-1]<x[i]) {xb <- x[i-1] breaks <-c(breaks, xb) k <- 1 }
判断条件xb<x[i-1]&&x[i-1]<x[i]的作用是:
- 保证前一个观测值
x[i-1]不是上一个断点的重复值 - 保证
x[i-1]和当前观测值x[i]不是重复值(没有ties)
满足条件时,就把x[i-1]设为新的断点,加入断点向量,同时把计数器k重置为1,开始攒下一个区间的观测。如果遇到重复值不满足判断条件,就不会切断点,k也不会重置,继续往下遍历,直到碰到相邻的不同值才切分,这时候区间的观测数就会大于h,符合题目描述的逻辑。
内容的提问来源于stack exchange,提问作者Magnus Moller
相关产品推荐
相关产品推荐

