如何使用purrr的map函数执行row-wise prop.tests并将结果添加到dataframe中?

问题描述 投票:0回答:3

我正在尝试解决 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)

没有给出想要的结果。任何帮助将不胜感激。

干杯,

路易丝

r dplyr purrr
3个回答
9
投票

我们可以在使用“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

6
投票

如果你想要一个新专栏,你可以使用@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

0
投票

问题提到了

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
© www.soinside.com 2019 - 2024. All rights reserved.