【问题标题】:Compute proportion of values by factor按因子计算值的比例
【发布时间】:2021-06-20 15:29:50
【问题描述】:

我有一个看起来像这样的数据框(18,000 行)。每行都有一个 p 值和一个附加的“频率”。频率是一个从 0 到 31 的因子。

 > head(df)
                  Gene P.value Frequency
    3  ENSG00000000419  1.000         1
    9  ENSG00000001084  0.851         2
    12 ENSG00000001461  0.699         4
    26 ENSG00000002746  0.113        23
    28 ENSG00000002834  0.529        12
    33 ENSG00000003137  0.464        31

如何创建一个新的数据框来计算每个频率的 P.values 的比例,即小于 0.01?

我希望结果如下所示:

> head(result_Df)

Frequency   Proportion
        0         0.02
        1         0.3
        2         0.02
        3         0.15

我认为 dplyr 可以很快地做到这一点,但我没有使用该软件包的经验。任何帮助表示赞赏!

【问题讨论】:

    标签: r dplyr tidyverse data-wrangling


    【解决方案1】:

    这是一种方法:

    
    library(data.table)
    setDT(result_Df)
    result_Df[ , .(Proportion = sum( P.value < .01 ) / .N ) , by=Frequency ]
    
    
    

    注意做事很快,然后做事尽可能少的代码行。

    这两件事都有优点,在基于 dplyr 的代码中肯定有后者的文化。

    data.table 的编写速度虽然很快,但在这种情况下可能更可取。 (肯定也很短)

    比较 18k 合成行的 dplyr 和 data.table 如下所示:

    
    lirary(data.table)
    library(microbenchmark)
    set.seed(100)
    n <- 18e3
    synthetic_Df = data.frame(
        Gene = sprintf( "ENSG%011d", ceiling(runif( n, min=1, max=2e4 )) ),
        P.value = runif( n ),
        Frequency = ceiling( runif( n, min=1, max=30 ) )
    )
    
    dt <- as.data.table(synthetic_Df)
    
    microbenchmark(
        dplyr = synthetic_Df %>% group_by( Frequency ) %>% summarize( Proporion = sum( P.value < .01 ) / n() ),
        data.table = dt[ , .(Proportion = sum( P.value < .01 ) / .N) , by=Frequency ]
    )
    
    
    

    输出:

    
    Unit: microseconds
           expr      min        lq      mean    median       uq      max neval cld
          dplyr 2004.720 2052.8060 2123.1076 2070.6640 2106.617 4793.772   100   b
     data.table  833.253  856.5115  915.5324  876.6245  904.607 3659.965   100  a 
    
    

    使用 data.table 快了 2.5 倍。这并不意味着 dplyr 方法在这种情况下不够好,很可能是这样。

    【讨论】:

      【解决方案2】:

      使用dplyr 的一种方式。将 1 分配给 P.value

      library(dplyr)
      
      df1 %>%
        group_by(Frequency) %>%
        summarise(Proportion = sum(ifelse(P.value < 0.01, 1, 0)) / n())
      

      示例数据和结果:

      df1 <- data.frame(Frequency = c(1,1,1,2,2,2),
                        P.value = c(0.001, 0.1, 0.2, 0.007, 0.009, 0.01))
      
      # A tibble: 2 x 2
        Frequency Proportion
            <dbl>      <dbl>
      1         1      0.333
      2         2      0.667
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-17
        • 1970-01-01
        相关资源
        最近更新 更多