我正在尝试解决 R 中的以下问题:我有一个包含两个变量(成功次数和总试验次数)的数据框。
# A tibble: 4 x 2
Success N
<dbl> <dbl>
1 28. 40.
2 12. 40.
3 22. 40.
4 8. 40.
我想对每一行执行 prop.test 或 binom.test 并将结果列表添加到数据帧(或其某些元素,如 p 值和 CI)。
理想情况下,我想添加第三列,其中包含 p 值和 CI 范围。到目前为止,我的尝试都非常失败。这是一个最小的编码示例:
Success <- c( 38, 12, 27, 9)
N <- c( 50, 50, 50, 50)
df <- as.tibble( cbind(Success, N))
df %>%
map( ~ prop.test, x = .$Success, n = .$N)
没有给出想要的结果。任何帮助将不胜感激。
干杯,
路易丝
我们可以在使用“prop.test”参数更改列名称后使用
pmap
pmap(setNames(df, c("x", "n")), prop.test)
或使用
map2
map2(df$Success, df$N, prop.test)
map
的问题在于它循环遍历数据集的每一列,并且它是list
s的
vector
df %>%
map(~ .x)
#$Success
#[1] 38 12 27 9
#$N
#[1] 50 50 50 50
所以,我们不能做
.x$Success
或 .x$N
正如 @Steven Beaupre 提到的,如果我们需要创建具有 p 值和置信区间的新列
res <- df %>%
mutate(newcol = map2(Success, N, prop.test),
pval = map_dbl(newcol, ~ .x[["p.value"]]),
CI = map(newcol, ~ as.numeric(.x[["conf.int"]]))) %>%
select(-newcol)
# A tibble: 4 x 4
# Success N pval CI
# <dbl> <dbl> <dbl> <list>
#1 38.0 50.0 0.000407 <dbl [2]>
#2 12.0 50.0 0.000407 <dbl [2]>
#3 27.0 50.0 0.671 <dbl [2]>
#4 9.00 50.0 0.0000116 <dbl [2]>
“CI”列是 2 个元素的
list
,可以对其进行 unnest
使其成为“长”格式数据
res %>%
unnest
或创建 3 列
df %>%
mutate(newcol = map2(Success, N, ~ prop.test(.x, n = .y) %>%
{tibble(pvalue = .[["p.value"]],
CI_lower = .[["conf.int"]][[1]],
CI_upper = .[["conf.int"]][[2]])})) %>%
unnest
# A tibble: 4 x 5
# Success N pvalue CI_lower CI_upper
# <dbl> <dbl> <dbl> <dbl> <dbl>
#1 38.0 50.0 0.000407 0.615 0.865
#2 12.0 50.0 0.000407 0.135 0.385
#3 27.0 50.0 0.671 0.395 0.679
#4 9.00 50.0 0.0000116 0.0905 0.319
如果你想要一个新专栏,你可以使用@akrun的方法,但在
dplyr
中撒上一点
broom
和
purrr
library(tidyverse) # for dplyr, purrr, tidyr & co.
library(broom)
analysis <- df %>%
set_names(c("x","n")) %>%
mutate(result = pmap(., prop.test)) %>%
mutate(result = map(result, tidy))
从那里给你一个整齐的嵌套小标题的结果。如果您只想将其限制为某些变量,您只需按照
mutate
/map
将函数应用于嵌套框架,然后 unnest() 即可。
analysis %>%
mutate(result = map(result, ~select(.x, p.value, conf.low, conf.high))) %>%
unnest(cols = c(result))
# A tibble: 4 x 5
x n p.value conf.low conf.high
<dbl> <dbl> <dbl> <dbl> <dbl>
1 38.0 50.0 0.000407 0.615 0.865
2 12.0 50.0 0.000407 0.135 0.385
3 27.0 50.0 0.671 0.395 0.679
4 9.00 50.0 0.0000116 0.0905 0.319
问题提到了
prop.test
和binom.test
,但另一种选择是binom::binom.confint
,当您成功为零时估计置信区间时,它非常有用,请参阅这里、这里和这里。如果使用此功能,以下内容可能有用:
library(tidyverse)
library(binom)
df %>%
rowwise() %>%
mutate(binom_test_var = list(binom.confint(x = Success, n = N, method = c("wilson")))) %>%
unnest(cols = c(binom_test_var))
# # A tibble: 4 × 8
# Success N method x n mean lower upper
# <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 38 50 wilson 38 50 0.76 0.626 0.857
# 2 12 50 wilson 12 50 0.24 0.143 0.374
# 3 27 50 wilson 27 50 0.54 0.404 0.670
# 4 9 50 wilson 9 50 0.18 0.0977 0.308