首页 > 解决方案 > 列表数据的对应总和

问题描述

我正在尝试用 R 对长度为 1000 的 0,1 序列进行 500 次模拟。并试图找出连续 3 个步骤的平均步骤。这实际上与计算抛硬币连续 3 次正面朝上的预期次数相同。rle 代表运行长度编码函数,它接受一个序列并将其转换为连续元素的运行序列。

uu<-matrix(sample(c(0,1),500000,replace = TRUE,prob = c(1/2,1/2)),ncol = 1000)
yy<-apply(uu,1,rle)
f1<-function(yy){
  which(yy$lengths>2&yy$values==1)
}
tt<-sapply(yy,f1)
oo<-sapply(tt, function(tt) return(tt[1]))

在我得到 tt 的第一个元素之后,这意味着 3 个连续正面的第一个序列。我想对前 3 个连续正面前的投掷进行 cumsum 或求和。而且我不知道如何做500次相应的。

f2<-function(yy){sum(yy$length[1:oo[1:500]])+3}
kk<-sapply(yy,f2)
mean(kk)

但是,f2 不起作用,因为 R 只捕获 oo 的第一个元素。我想知道如何对 yy$length 和 oo 的相应元素求和?请告诉我是否有更方便的方法来进行此模拟。非常感谢。

标签: r

解决方案


If I understand correctly, the OP wants to simulate how many throws it takes on average until exactly 3 heads occur consecutively.

Here is an example how this can be solved using replicate():

nt <- 20L # number of throws in a sequence
nr <- 10L # number of repetitions
set.seed(42) # for reproducible results
mean(
  replicate(
    nr, { 
      throws <- sample(0:1, nt, replace = TRUE)
      print(throws)
      throws_rle <- rle(throws)
      rle_len <- throws_rle[["lengths"]]
      rle_val <- throws_rle[["values"]]
      idx_first_3_heads <- head(which(rle_val == 1L & rle_len == 3L), 1L)
      # add lengths of previous throws
      n_previous_throws <- if (length(idx_first_3_heads) > 0) 
      {
        sum(head(rle_len, idx_first_3_heads - 1L))
      } else {
        NA
      }
      cat("First occurrence of exactly 3 heads after", n_previous_throws, "throws\n")
      n_previous_throws
    }
  ),
  na.rm = TRUE
)
 [1] 0 0 0 0 1 1 1 1 0 1 0 1 0 1 0 0 1 1 1 1
First occurrence of exactly 3 heads after NA throws
 [1] 0 0 0 0 0 1 0 0 0 0 1 1 1 1 0 1 0 1 1 1
First occurrence of exactly 3 heads after 17 throws
 [1] 0 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 0 1 0 0
First occurrence of exactly 3 heads after NA throws
 [1] 0 1 1 1 1 1 1 0 1 0 1 0 1 1 1 1 0 0 0 0
First occurrence of exactly 3 heads after NA throws
 [1] 1 0 1 0 0 1 1 0 0 0 0 1 0 1 1 1 0 1 1 1
First occurrence of exactly 3 heads after 13 throws
 [1] 1 1 0 1 0 1 1 0 1 0 1 0 1 0 1 1 0 0 0 1
First occurrence of exactly 3 heads after NA throws
 [1] 0 1 1 1 1 0 0 1 0 0 0 1 0 0 1 1 1 0 0 1
First occurrence of exactly 3 heads after 14 throws
 [1] 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 1
First occurrence of exactly 3 heads after 9 throws
 [1] 0 1 1 0 1 1 0 0 1 0 1 0 1 1 0 1 0 1 1 1
First occurrence of exactly 3 heads after 17 throws
 [1] 1 1 1 0 1 1 1 0 1 1 0 1 1 1 1 1 0 0 1 1
First occurrence of exactly 3 heads after 0 throws
[1] 11.66667

Note that this code hopefully is self-explaining and is just for demonstration. It will need to be streamlined for production use.

The if clause is required to distinguish between the situation

  • where no 3 consecutive heads occur at all in a sequence (returns NA)
  • and where the 3 consecutive heads occur right at the start (returns 0 as there are no previous throws).

Both situations can be found in the sample use case.


推荐阅读