基于R语言统计硬币翻转序列频率:扩展至任意长度方法咨询
问题解答
你的两次尝试都不正确,因为没有生成真正连续的3次硬币翻转序列。比如,3次序列应该是第1-3次、第2-4次……第998-1000次的连续组合,而你的代码里重复使用head或tail,导致序列元素并非连续偏移。
正确统计3次翻转序列的代码
# 生成连续的3次翻转序列 Triples <- data.frame( first = My_Data$Results[1:(nrow(My_Data)-2)], second = My_Data$Results[2:(nrow(My_Data)-1)], third = My_Data$Results[3:nrow(My_Data)] ) # 统计频率 Final <- as.data.frame(table(Triples))
这段代码通过索引偏移,分别取出每一组连续的3个翻转结果,比如第1、2、3个元素组成第一组,第2、3、4个组成第二组,以此类推,最终得到的才是真实的3次翻转序列频率。
1. 适配任意长度序列的通用逻辑
可以写一个通用函数,支持传入任意序列长度k,自动生成对应长度的连续序列并统计频率:
count_sequences <- function(results, k) { total_flips <- length(results) if (k > total_flips) stop("序列长度不能超过总翻转次数") # 生成k个偏移后的结果向量:第1个向量从第1位开始,第2个从第2位开始...第k个从第k位开始 sequence_list <- lapply(0:(k-1), function(offset) { results[(1 + offset):(total_flips - k + 1 + offset)] }) # 转换为数据框并设置列名 sequence_df <- do.call(data.frame, sequence_list) colnames(sequence_df) <- paste0("pos", 1:k) # 统计频率并返回 as.data.frame(table(sequence_df)) } # 示例:统计3次序列 count_sequences(My_Data$Results, 3) # 示例:统计5次序列 count_sequences(My_Data$Results, 5)
函数核心逻辑是通过索引偏移生成每一组连续序列:对于长度为k的序列,总共有total_flips - k + 1组,每组的元素分别是原结果中第i、i+1...i+k-1位的元素。
2. 大数据量下的高效计算方法
当数据量极大(如百万次以上翻转),用多列数据框+table的方法效率较低,推荐将连续序列拼接成字符串,再用高效的分组统计工具处理:
方法1:字符串拼接+基础table
count_sequences_fast <- function(results, k) { total_flips <- length(results) if (k > total_flips) stop("序列长度不能超过总翻转次数") # 将每组连续k个翻转结果拼接成字符串(如"HHH"、"HTT") sequences <- sapply(1:(total_flips - k + 1), function(i) { paste(results[i:(i+k-1)], collapse = "") }) # 统计频率并返回数据框 as.data.frame(table(sequences), stringsAsFactors = FALSE) }
方法2:用dplyr加速分组统计
library(dplyr) count_sequences_dplyr <- function(results, k) { total_flips <- length(results) if (k > total_flips) stop("序列长度不能超过总翻转次数") sequences <- sapply(1:(total_flips - k + 1), function(i) { paste(results[i:(i+k-1)], collapse = "") }) # 用dplyr的count高效统计 tibble(sequence = sequences) %>% count(sequence, name = "Freq") }
方法3:用data.table实现极致效率
如果数据量达到千万级,data.table的分组统计速度远快于基础函数和dplyr:
library(data.table) count_sequences_dt <- function(results, k) { total_flips <- length(results) if (k > total_flips) stop("序列长度不能超过总翻转次数") sequences <- sapply(1:(total_flips - k + 1), function(i) { paste(results[i:(i+k-1)], collapse = "") }) # data.table分组计数 data.table(sequence = sequences)[, .(Freq = .N), by = sequence] }
这些方法的核心是将多元素序列转换为单一字符串,减少数据结构的复杂度,同时利用高效的分组统计工具提升计算速度。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

