【问题标题】:dplyr how to calculate percent of multiple columns and output columns with custom namesdplyr如何计算多列的百分比并使用自定义名称输出列
【发布时间】:2021-09-18 14:44:20
【问题描述】:

我想计算数据框中每一列的百分比,并为每一列设置一个自定义名称。

考虑以下代码:

a<-structure(list(year = 2000:2005, Col1 = 1:6, Col2 = c(1L, 4L, 
9L, 16L, 25L, 36L)), row.names = c(NA, -6L), class = "data.frame")
> a
  year Col1 Col2
1 2000    1    1
2 2001    2    4
3 2002    3    9
4 2003    4   16
5 2004    5   25
6 2005    6   36
a<-a %>% rowwise() %>%
mutate(total = sum(across(starts_with("Col")), na.rm = T)) %>% data.frame()
a %>%
    mutate_at(vars(starts_with("Col")) , funs(P = ./a$total * 100))

输出如下:

如何处理最后两列的名称(例如 per_Col1 和 per_Col2 而不是 Col1_P 和 Col2_P,主要问题)?有没有更好的方法(使用 dplyr 包)来做到这一点?(而不是计算列的总和,然后将每一列除以它)

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    您可以将 cross 与 .names 参数一起使用:

    a %>%
      rowwise() %>%
      mutate(total = sum(across(starts_with("Col")), na.rm = TRUE)) %>% 
      mutate(across(starts_with("Col") , ~./total * 100, .names = 'per_{col}')) %>%
      ungroup()
    

    给出:

    # A tibble: 6 x 6
       year  Col1  Col2 total per_Col1 per_Col2
      <int> <int> <int> <int>    <dbl>    <dbl>
    1  2000     1     1     2     50       50  
    2  2001     2     4     6     33.3     66.7
    3  2002     3     9    12     25       75  
    4  2003     4    16    20     20       80  
    5  2004     5    25    30     16.7     83.3
    6  2005     6    36    42     14.3     85.7
    

    【讨论】:

      【解决方案2】:

      这里是使用scales 的稍微不同的方法:

      library(scales)
      library(dplyr)
      a %>%
          rowwise() %>% 
          mutate(Total = sum(c_across(Col1:Col2), na.rm = TRUE), 
                 across(Col1:Col2, ~percent(./sum(Total), accuracy = 0.1), .names ="percent_{.col}")
                 )
      

      输出

         year  Col1  Col2 Total percent_Col1 percent_Col2
        <int> <int> <int> <int> <chr>        <chr>       
      1  2000     1     1     2 50.0%        50.0%       
      2  2001     2     4     6 33.3%        66.7%       
      3  2002     3     9    12 25.0%        75.0%       
      4  2003     4    16    20 20.0%        80.0%       
      5  2004     5    25    30 16.7%        83.3%       
      6  2005     6    36    42 14.3%        85.7% 
      

      【讨论】:

        【解决方案3】:

        我们可以使用rowSums 来使这个向量化

        library(dplyr)
        a %>%
            mutate(total = rowSums(across(starts_with('Col'))), 
             across(starts_with('Col'), ~ ./total * 100, .names = 'per_{.col}'))
          year Col1 Col2 total per_Col1 per_Col2
        1 2000    1    1     2 50.00000 50.00000
        2 2001    2    4     6 33.33333 66.66667
        3 2002    3    9    12 25.00000 75.00000
        4 2003    4   16    20 20.00000 80.00000
        5 2004    5   25    30 16.66667 83.33333
        6 2005    6   36    42 14.28571 85.71429
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-01-21
          • 2022-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多