如何编写R函数从向量末尾提取首个连续5个TRUE值?
从向量末尾提取首个连续5个TRUE值的R函数实现
需求说明
给定以下逻辑向量:
x <- c(F, T, T, T, F, T, T, T, T, T) names(x) <- letters[1:10] y <- c(T, F, T, T, T, F, T, T, T, T) names(y) <- letters[1:10] z <- c(T, T, F, T, T, T, T, T, F, F) names(z) <- letters[1:10] a <- c(T, T, T, T, T, F, T, F, T, T, T, T, T) names(a) <- letters[1:13]
需要编写函数实现:
- 传入
x时,返回从末尾开始的首个连续5个TRUE(即f到j) - 传入
y时,返回NA(不存在从末尾开始的连续5个TRUE) - 传入
z时,返回中间的连续5个TRUE(即d到h) - 传入
a时,返回末尾的连续5个TRUE(即i到m)
解决方案
以下是实现该功能的函数:
extract_last_consec_true <- function(vec, n = 5) { if (!is.logical(vec)) { stop("输入必须是逻辑向量") } rev_vec <- rev(vec) rle_obj <- rle(rev_vec) for (i in seq_along(rle_obj$values)) { if (rle_obj$values[i] && rle_obj$lengths[i] >= n) { start_pos <- sum(rle_obj$lengths[1:(i-1)]) + 1 end_pos <- start_pos + rle_obj$lengths[i] - 1 target_rev_pos <- (end_pos - n + 1):end_pos original_pos <- length(vec) - target_rev_pos + 1 return(vec[original_pos]) } } return(NA) }
函数逻辑说明
- 输入校验:先判断输入是否为逻辑向量,避免非逻辑值导致错误;
- 反转向量:将原向量反转,让原末尾的元素位于新向量开头,方便从原末尾开始查找;
- 游程编码:用
rle()函数压缩反转后的向量,得到连续相同值的长度和对应值; - 查找目标游程:遍历游程编码结果,找到第一个(最靠近原向量末尾)的TRUE游程,且长度不小于5;
- 定位并返回结果:计算该游程在原向量中的位置,截取连续5个TRUE返回;若没有符合条件的游程,返回
NA。
测试验证
运行以下代码验证函数效果:
# 测试x extract_last_consec_true(x) # 输出: # f g h i j # TRUE TRUE TRUE TRUE TRUE # 测试y extract_last_consec_true(y) # 输出:NA # 测试z extract_last_consec_true(z) # 输出: # d e f g h # TRUE TRUE TRUE TRUE TRUE # 测试a extract_last_consec_true(a) # 输出: # i j k l m # TRUE TRUE TRUE TRUE TRUE
内容的提问来源于stack exchange,提问作者Shawn Brar
相关产品推荐
相关产品推荐

