提问人:stats_noob 提问时间:11/22/2021 最后编辑:stats_noob 更新时间:11/23/2021 访问量:238
R:计算条件在数据框中出现的次数
R: Counting the Number of Times a Condition Appears in a Data Frame
问:
我正在使用 R 编程语言。我想到了以下我想测试的问题:
- 假设有一枚硬币有 5% 的几率落在正面,95% 的几率落在反面
基于计算机模拟,我想找出以下内容:
观察 HEADS, TAILS, HEADS 之前的最小翻转次数
观察 HEADS、TAILS、HEADS 之前的平均翻转次数
观察 HEADS, TAILS, HEADS 之前的最大翻转次数
我试图用 R 编写一个模拟,将这枚硬币翻转三次,我称之为“运行”。然后,模拟执行 100 次“运行”:
results <- list()
for (i in 1:100){
response_i <- c("H","T")
response_i <- sample(response_i, 3, replace=TRUE,
prob=c(0.05, 0.95))
response_i <- as.factor(response_i)
iteration_i = i
run_i = data.frame(response_i, iteration_i)
results[[i]] <- run_i
}
这如下所示(例如,运行 #22、#23、#24):
[[22]]
response_i iteration_i
1 T 22
2 T 22
3 T 22
[[23]]
response_i iteration_i
1 H 23
2 T 23
3 T 23
[[24]]
response_i iteration_i
1 T 24
2 T 24
3 T 24
我的问题:
我想修改上面的代码,以便:
1)在你看到第一个H、T、H后,模拟会自动停止(现在,我运行了100次模拟,希望这足以观察到至少一个H、T、T)
2) 一旦第一个 H、T、H 出现并且模拟自动停止,我想记录这是在哪个“运行”发生的(即“iteration_i”的值是多少?
3) 然后我想重复整个模拟 100 次(100 次运行 * 100 次 = 10,000 次抛硬币)
一旦完成,我将能够制作直方图,显示观察到 H、T、H 之前的最小抛硬币次数、平均抛硬币次数和最大抛硬币次数(使用“ggplot2”,我认为这不会太难)。
#sample data
number_of_runs_before_HTH_appeared = c(15,10, 11, 8, 12, 21, 32, 7, 9, 20, 22, 3, 16, 7 )
hist(number_of_runs_before_HTH_appeared, main = "Number of Runs before HTH")
但是有人可以帮我格式化/修改我的代码以简化我想要实现的目标吗?目前,我使用以下 R 代码来“整理”第一次模拟的 100 次“运行”:
results_df <- do.call(rbind.data.frame, results)
head(results_df)
response_i iteration_i
1 T 1
2 T 1
3 T 1
4 T 2
5 T 2
6 T 2
然后我手动重复了很多次,例如。g
results_df_1 <- do.call(rbind.data.frame, results)
results_df_1$index = 1
#re-run original simulation
results_df_2<- do.call(rbind.data.frame, results)
results_df_2$index = 2
#re-run original simulation (many times)
results_df_n<- do.call(rbind.data.frame, results)
results_df_n$index = n
final <- data.frame(results_df_1, results_df_2, results_df_n)
然后,我将这个“最终”文件导入Microsoft Excel,并尝试手动折叠“最终文件”以回答我的三个原始问题 - 但我希望有人可以通过修改R中的原始代码来向我展示如何做到这一点。
有人可以帮我解决这个问题吗?
谢谢!
答:
这可能会让你开始
library(data.table)
n <- 100
simulations <- 100
# build data.table with simulations
DT <- data.table(sim = rep(1:simulations, each = n),
step = 1:n,
flip = lapply(
lapply(seq.int(n * simulations),
function(x) sample(c("H","T"), 3, replace=TRUE, prob=c(0.05, 0.95))),
paste0, collapse = ""))
# sim step flip
# 1: 1 1 TTT
# 2: 1 2 TTT
# 3: 1 3 TTT
# 4: 1 4 TTT
# 5: 1 5 TTT
# ---
# 9996: 100 96 THT
# 9997: 100 97 TTT
# 9998: 100 98 TTT
# 9999: 100 99 TTT
# 10000: 100 100 TTT
DT
# find the first step where flip == "HTH" for each sim
DT[flip == "HTH", .(first_hth = min(step)), by = .(sim)]
# sim first_hth
# 1: 2 88
# 2: 6 30
# 3: 7 16
# 4: 19 38
# 5: 26 42
# 6: 28 91
# 7: 34 87
# 8: 36 96
# 9: 38 98
# 10: 45 74
# 11: 48 93
# 12: 51 46
# 13: 53 30
# 14: 60 70
# 15: 68 27
# 16: 69 53
# 17: 88 35
# 18: 91 88
# 19: 94 74
# 20: 95 100
# 21: 97 81
# 22: 98 24
# sim first_hth
评论
for 和 while 循环的组合将达到您的目的。
for 循环将运行您想要重复测试的次数,而 while 循环将帮助您在第一次 H T H 组合发生时停止测试。
以下是您可以使用并继续执行进一步步骤的代码。
results <- list()
for (j in 1:100) {
response_i <- ''
i <- 1
while (response_i != 'HTH') {
response_i <- c("H","T")
response_i <- sample(response_i, 3, replace=TRUE,
prob=c(0.05, 0.95))
response_i <- paste(response_i, collapse = '')
iteration_i = i
if (response_i == 'HTH') {
run_i = data.frame(response_i, iteration_i)
results[[j]] <- run_i
}
i <- i + 1
}
}
data <- do.call('rbind', results)
head(data)
response_i iteration_i
1 HTH 1206
2 HTH 46
3 HTH 116
4 HTH 1633
5 HTH 889
6 HTH 43
评论
library(tidyverse)
set.seed(42)
coin_flip <- crossing(trial = seq_len(1000),
flips = 1:1000) %>%
mutate(heads = rbinom(n(), 1, .05)) %>%
group_by(trial) %>%
mutate(second_flip = lead(heads),
third_flip = lead(heads,2),
hth = heads & !second_flip & third_flip) %>%
summarise(first_hth = which(hth)[1]+2)
coin_flip %>% head()
#> # A tibble: 6 x 2
#> trial first_hth
#> <int> <dbl>
#> 1 1 46
#> 2 2 31
#> 3 3 114
#> 4 4 NA
#> 5 5 776
#> 6 6 292
coin_flip %>% ggplot(aes(first_hth))+
geom_histogram()
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#> Warning: Removed 96 rows containing non-finite values (stat_bin).
由 reprex 包 (v2.0.1) 于 2021-11-22 创建
评论