【问题标题】:Use condition in summarise_at in dplyr在 dplyr 的 summarise_at 中使用条件
【发布时间】:2019-07-30 03:54:17
【问题描述】:

我希望能够使用条件来过滤 summarise_at 调用中汇总的内容。我知道这可以在直接调用 dplyr:: summarise() 时完成,但我想避免为每个变量指定这个。

我提供了以下代码,认为对 summarise_at 的调用会给我正确的数据。但事实并非如此。我希望代码返回标记为最终数据的数据集。仅当行与过滤条件匹配时,每个人都有一行,每个变量求和。当它不匹配或没有什么可以总结时,我希望它返回 0 或 NA。

Data = tibble(Group = c(1,1,1,1,1,1,1,1),
              Week = c(1,2,3,4,1,2,3,4),
              Condition = c(1,1,1,0,0,1,1,0),
              Var1 = 1:8,
              Var2 = 9:16,
              Var3 = 17:24)

Data %>% 
    group_by(Group, Week, Condition) %>% 
    summarise_at(vars(Var1, Var2, Var3), ~sum(., na.rm = T)) %>%
    ungroup()


Final.Data = tibble(Group = c(1,1,1,1),
                    Week = c(1,2,3,4),
                    Var1 = c(1,8,10,0),
                    Var2 = c(9,24,26,0),
                    Var3 = c(17,40,42,0))

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    一种选择是在“组”、“周”上执行group_by,然后在starts_with(“Var”)的列上使用summarise_at,根据中的二进制值对每个列进行子集化'Condition' 可以用as.logical 转换为逻辑,因此 1-> TRUE 和 0 -> FALSE,并得到每一列的sum

    library(dplyr)
    Data %>% 
        group_by(Group, Week) %>% 
        summarise_at(vars(starts_with("Var")), ~ 
                sum(.[as.logical(Condition)], na.rm = TRUE)) %>%
        ungroup
    # A tibble: 4 x 5
    #  Group  Week  Var1  Var2  Var3
    #  <dbl> <dbl> <int> <int> <int>
    #1     1     1     1     9    17
    #2     1     2     8    24    40
    #3     1     3    10    26    42
    #4     1     4     0     0     0
    

    如果还有其他值,则使用==

    Data %>% 
        group_by(Group, Week) %>% 
        summarise_at(vars(starts_with("Var")),
          ~ sum(.[Condition == 1], na.rm = TRUE)) %>%
        ungroup
    

    或者我们可以乘以“条件”,因为任何值乘以 0 得到 0,而 1 得到数字本身,然后执行sum

    Data %>% 
       group_by(Group, Week) %>% 
       summarise_at(vars(matches("Var")), ~ sum(. * Condition))
    

    或者使用data.table

    library(data.table)
    setDT(Data)[, lapply(.SD, function(x) sum(x[Condition == 1], na.rm = TRUE)),
           by =  .(Group, Week), .SDcols = grep("Var", names(Data))]
    #   Group Week Var1 Var2 Var3
    #1:     1    1    1    9   17
    #2:     1    2    8   24   40
    #3:     1    3   10   26   42
    #4:     1    4    0    0    0
    

    或者使用base R 中的选项和rowsum

    rowsum(Data[4:6] * Data$Condition, group = do.call(paste, Data[1:2]))
    

    或使用by

    do.call(rbind, by(Data[-(1:2)], Data[1:2], FUN = function(x) colSums(x[-1] * x[,1])))
    

    【讨论】:

      【解决方案2】:

      你可以sumCondition == 1

      library(dplyr)
      
      Data %>% 
        group_by(Group, Week) %>% 
        summarise_at(vars(Var1, Var2, Var3), ~sum(.[Condition == 1], na.rm = TRUE)) %>%
        ungroup()
      
      # A tibble: 4 x 5
      #  Group  Week  Var1  Var2  Var3
      #  <dbl> <dbl> <int> <int> <int>
      #1     1     1     1     9    17
      #2     1     2     8    24    40
      #3     1     3    10    26    42
      #4     1     4     0     0     0
      

      或者另一种选择是将Week 设为factor, filter 其中Condition == 1 并取sum

      Data %>% 
        mutate(Week = factor(Week, levels = unique(Week))) %>%
        filter(Condition == 1) %>%
        group_by(Group, Week, .drop = FALSE) %>% 
        summarise_at(vars(Var1, Var2, Var3), sum, na.rm = TRUE)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-03
        • 1970-01-01
        • 1970-01-01
        • 2015-03-20
        • 1970-01-01
        • 2019-12-20
        相关资源
        最近更新 更多