You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正R语言n序列频率统计函数,补全遗漏的末尾序列?

一、修复遗漏最后一个序列的问题

原函数的索引范围写错了——对于长度为L的序列,长度为n的连续子序列总数是L - n + 1,原代码里用了1:(length(results) - n),少算了最后一个子序列的位置。把索引范围改成1:(length(results) - n + 1)就能解决问题:

n_sequences <- function(n, results) {
  helper <- function(i, n) if (n < 1) "" else sprintf(
    "%s%s", 
    helper(i, n - 1), 
    results[i + n - 1]
  )
  result <- data.frame(
    table(
      sapply(
        1:(length(results) - n + 1),  # 此处修改索引范围
        function(i) helper(i, n)
      )
    )
  )
  colnames(result) <- c("Sequence", "Frequency")
  result
}

# 测试验证
Results <- c(0,0,0,1,1,1,0,1,0,1,1)
n_sequences(4, Results)

运行后结果会包含遗漏的1011序列。


二、其他统计连续序列频率的方法

1. stringr包简洁实现

把数字序列转成字符串,直接滑动截取所有长度为n的子串再统计:

library(stringr)

count_sequences_str <- function(n, results) {
  seq_str <- paste(results, collapse = "")
  sequences <- str_sub(seq_str, start = 1:(nchar(seq_str)-n+1), end = n:(nchar(seq_str)))
  result <- as.data.frame(table(sequences))
  colnames(result) <- c("Sequence", "Frequency")
  result
}

count_sequences_str(4, Results)

2. zoo包rollapply滑动窗口

用滑动窗口函数直接处理向量,代码更简洁:

library(zoo)

count_sequences_roll <- function(n, results) {
  sequences <- rollapply(results, width = n, FUN = function(x) paste(x, collapse = ""))
  result <- as.data.frame(table(sequences))
  colnames(result) <- c("Sequence", "Frequency")
  result
}

count_sequences_roll(4, Results)

3. 基础R向量化方法(替代递归)

递归的helper函数效率偏低,用矩阵索引生成所有子序列更高效:

count_sequences_base <- function(n, results) {
  L <- length(results)
  idx_matrix <- matrix(1:(L - n + 1) + rep(0:(n-1), each = L - n + 1), ncol = n)
  sequences <- apply(idx_matrix, 1, function(idx) paste(results[idx], collapse = ""))
  result <- as.data.frame(table(sequences))
  colnames(result) <- c("Sequence", "Frequency")
  result
}

count_sequences_base(4, Results)

三、计算条件概率的思路

以“出现三个0后,下一个数字是1的概率”为例,本质是:
P(下一个是1 | 前三个是0) = 序列"0001"的频率 / 所有以"000"开头的序列总频率

可以通过统计n长度序列和n-1长度前缀序列的频率,匹配后计算:

calc_conditional_prob <- function(prefix, n, results) {
  # 统计n长度序列频率
  seq_n <- count_sequences_str(n, results)
  # 统计n-1长度前缀序列频率
  seq_n_minus_1 <- count_sequences_str(n-1, results)
  
  # 筛选以目标前缀开头的n长度序列
  target_seqs <- seq_n[startsWith(seq_n$Sequence, prefix), ]
  # 获取目标前缀的总出现频率
  prefix_freq <- seq_n_minus_1[seq_n_minus_1$Sequence == prefix, "Frequency"]
  
  # 计算每个后缀的条件概率
  target_seqs$ConditionalProb <- target_seqs$Frequency / prefix_freq
  target_seqs
}

# 测试:三个0之后下一个是1的概率
calc_conditional_prob("000", 4, Results)

内容的提问来源于stack exchange,提问作者stats_noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:46:13