【问题标题】:How to use purrr's map function to perform row-wise prop.tests and add results to the dataframe?如何使用 purrr 的 map 函数执行逐行 prop.tests 并将结果添加到数据框?
【发布时间】:2018-03-11 16:36:11
【问题描述】:

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


    【解决方案1】:

    我们可以用'prop.test'的参数改变列名后使用pmap

    pmap(setNames(df, c("x", "n")), prop.test)
    

    或使用map2

    map2(df$Success, df$N, prop.test)
    

    map 的问题在于它循环遍历数据集的每一列,它是vectors 中的list

    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,可以通过 unnested 使其成为“长”格式数据

    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
    

    【讨论】:

    • 小贴士:如果你给map一个字符串而不是一个函数,它可以作为一个提取器,所以pval = map_dbl(newcol, ~ .x[["p.value"]])实际上可以是pval = map_dbl(newcol, "p.value")
    【解决方案2】:

    如果您想要一个新专栏,您可以使用@akrun 的方法,但在purrr 中添加一点dplyrbroom

    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)) 
    

    从那里给你一个整洁的嵌套 tibble 的结果。如果您只想将其限制为某些变量,您只需按照 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
    

    【讨论】:

    • 警告信息:cols 现在是必需的。请使用cols = c(result) unnest(cols=c("result"))
    猜你喜欢
    • 1970-01-01
    • 2021-12-22
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-19
    相关资源
    最近更新 更多