【问题标题】:R summarize_if more complex functions to multiple columnsR summarise_if 更复杂的函数到多列
【发布时间】:2020-08-30 14:02:40
【问题描述】:

您好,我正在寻找一个优雅的解决方案,理想地结合 dplyr&purr。

我将按 id 对数据进行分组,然后我有 4 个数字列,我想应用到所有这些列 列求和函数。另外,我想根据 diff 列将条件总和应用于这 4 个数字列。

所以说具体一点,我想总结所有 4 列的总和,diff

我从这个开始但被卡住了

df%>%group_by(id)%>%summarise_if(is.numeric,.funs = (sum,~sum(.[diff<11])) 


    df<-structure(list(id = c(10274565, 10274449, 10274449, 10274449, 
10274565, 10274557, 10274557, 10274449, 10274565, 10274565, 10274565, 
10274557, 10274565, 10274557, 10274557, 10274557, 10274557, 10274557, 
10274557, 10274449, 10274449), d_amt = c(70L, 52L, 47L, 31L, 
100L, 17L, 74L, 54L, 83L, 90L, 76L, 98L, 73L, 49L, 81L, 82L, 
80L, 24L, 30L, 21L, 43L), d_cnt = c(3L, 4L, 3L, 3L, 5L, 3L, 1L, 
3L, 1L, 3L, 3L, 3L, 5L, 1L, 4L, 1L, 1L, 5L, 4L, 4L, 5L), w_amt = c(74L, 
16L, 20L, 73L, 22L, 11L, 61L, 90L, 78L, 94L, 64L, 58L, 84L, 15L, 
42L, 31L, 53L, 92L, 76L, 14L, 65L), w_cnt = c(4L, 5L, 1L, 1L, 
5L, 2L, 4L, 3L, 3L, 2L, 5L, 1L, 4L, 1L, 4L, 4L, 1L, 1L, 4L, 3L, 
1L), diff = structure(c(43, 30, 20, 16, 22, 57, 50, 40, 64, 51, 
50, 8, 88, 85, 79, 43, 28, 22, 17, 13, 3), class = "difftime", units = "days")), row.names = c(NA, 
-21L), class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    你可以试试:

    library(dplyr)
    
    df %>%
      group_by(id) %>%
      summarise(
        across(
          where(is.integer),
          list(below11 = ~ sum(.[diff < 11]),
               below21 = ~ sum(.[diff < 21]))
        )
      )
    

    输出:

    # A tibble: 3 x 9
            id d_amt_below11 d_amt_below21 d_cnt_below11 d_cnt_below21 w_amt_below11 w_amt_below21 w_cnt_below11 w_cnt_below21
         <dbl>         <int>         <int>         <int>         <int>         <int>         <int>         <int>         <int>
    1 10274449            43           142             5            15            65           172             1             6
    2 10274557            98           128             3             7            58           134             1             5
    3 10274565             0             0             0             0             0             0             0             0
    

    请注意,示例中的列似乎是 integer,因此是 is.integer 部分。

    【讨论】:

      【解决方案2】:

      你可以使用:

      library(dplyr)
      df %>%
        group_by(id) %>%
        summarise(across(where(is.numeric), ~sum(.[diff < 11])))
      
      #        id d_amt d_cnt w_amt w_cnt
      #     <dbl> <int> <int> <int> <int>
      #1 10274449    43     5    65     1
      #2 10274557    98     3    58     1
      #3 10274565     0     0     0     0
      

      或者,如果您使用的是旧版本的dplyr

      df %>%
        group_by(id) %>%
        summarise_if(is.numeric, ~sum(.[diff < 11]))
      

      【讨论】:

        【解决方案3】:

        您可以按diff 列分组,然后按组进行汇总:

        library(dplyr)
        df %>% 
          mutate(dif_cat = case_when(diff < 11 ~ "<11",
                                     diff < 22 ~ "<22",
                                     TRUE ~ ">=22")) %>% 
          group_by(id, dif_cat) %>% 
          summarise(across(where(is.numeric), ~sum(.)))
        
        
        # A tibble: 7 x 6
        # Groups:   id [3]
                id dif_cat d_amt d_cnt w_amt w_cnt
             <dbl> <chr>   <int> <int> <int> <int>
        1 10274449 <11        43     5    65     1
        2 10274449 <22        99    10   107     5
        3 10274449 >=22      106     7   106     8
        4 10274557 <11        98     3    58     1
        5 10274557 <22        30     4    76     4
        6 10274557 >=22      407    16   305    17
        7 10274565 >=22      492    20   416    23
        
        

        【讨论】:

        • 其实这些范围是允许重叠的,所以它是 0 和 11 之间的差异,0 和 21 之间的差异......但这在其他情况下无论如何都是有用的
        猜你喜欢
        • 2020-04-04
        • 2021-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-16
        • 1970-01-01
        • 2016-09-05
        • 1970-01-01
        相关资源
        最近更新 更多