R:计算条件在数据框中出现的次数
R: Counting the Number of Times a Condition Appears in a Data Frame
我正在使用 R 编程语言。我想到了以下我想测试的问题:
- 假设有一枚硬币有 5% 的几率正面朝上,95% 的几率朝反面着陆
基于计算机模拟,我想找出以下内容:
观察正面、反面、正面之前的最少翻转次数
观察正面、反面、正面之前的平均翻转次数
观察正面、反面、正面前的最大翻转次数
我试着用 R 写了一个模拟,将这个硬币抛了 3 次,我称之为“运行”。然后模拟执行 100 "运行s":
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运行 s,并希望这足以 运行s 观察至少一个 H, T, T)
2)一旦第一个H,T,H出现,模拟自动停止,我想记录一下“运行”这个发生的地方(即“iteration_i”的值是多少?)
3) 然后我想重复整个模拟 100 次(100 运行s * 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")
但是有人可以帮助我 format/modify 我的代码来简化我想要实现的目标吗?目前,我使用以下 R 代码从第一次模拟中“整理”了 100 个“运行s”:
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
然后我手动重复了很多次,例如
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 package (v2.0.1)
于 2021-11-22 创建
我正在使用 R 编程语言。我想到了以下我想测试的问题:
- 假设有一枚硬币有 5% 的几率正面朝上,95% 的几率朝反面着陆
基于计算机模拟,我想找出以下内容:
观察正面、反面、正面之前的最少翻转次数
观察正面、反面、正面之前的平均翻转次数
观察正面、反面、正面前的最大翻转次数
我试着用 R 写了一个模拟,将这个硬币抛了 3 次,我称之为“运行”。然后模拟执行 100 "运行s":
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运行 s,并希望这足以 运行s 观察至少一个 H, T, T)
2)一旦第一个H,T,H出现,模拟自动停止,我想记录一下“运行”这个发生的地方(即“iteration_i”的值是多少?)
3) 然后我想重复整个模拟 100 次(100 运行s * 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")
但是有人可以帮助我 format/modify 我的代码来简化我想要实现的目标吗?目前,我使用以下 R 代码从第一次模拟中“整理”了 100 个“运行s”:
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
然后我手动重复了很多次,例如
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 package (v2.0.1)
于 2021-11-22 创建