【问题标题】:Select a maximum value across rows and columns with grouped data选择具有分组数据的行和列的最大值
【发布时间】:2019-01-06 03:37:58
【问题描述】:

下面的数据有一个 IndID 字段以及包含数字的三列,在某些情况下包括 NA,每个 IndID 的行数不同。

library(dplyr)
n = 10
set.seed(123)
dat <- data.frame(IndID = sample(c("AAA", "BBB", "CCC", "DDD"), n, replace = T),
                  Num1 = c(2,4,2,4,4,1,3,4,3,2),
                  Num2 = sample(c(1,2,5,8,7,8,NA), n, replace = T),
                  Num3 = sample(c(NA, NA,NA,8,7,9,NA), n, replace = T)) %>%
  arrange(IndID)

 head(dat)
  IndID Num1 Num2 Num3
1   AAA    1   NA    7
2   BBB    2   NA   NA
3   BBB    2    7    7
4   BBB    2   NA   NA
5   CCC    3    2    8
6   CCC    3    5   NA

对于每个IndID,我想创建一个新列Max,其中包含Num1:Num3 的最大值。在大多数情况下,这涉及找到跨多行和多列的最大值。在dplyr 中,我错过了最后一步(如下),如果有任何建议,我将不胜感激。

dat %>%
  group_by(IndID) %>%
  mutate(Max = "???")

【问题讨论】:

    标签: r dplyr max


    【解决方案1】:

    一个选项是pmax 来获得按行的最大值

    dat %>%        
       mutate(Max = pmax(Num1, Num2, Num3, na.rm = TRUE))
    

    如果有很多列,我们可以获取列名,将其转换为符号然后求值(!!!

    dat %>%        
        mutate(Max = pmax(!!! rlang::syms(names(.)[-1]), na.rm = TRUE))
    # A tibble: 10 x 5
    # Groups:   IndID [4]
    #   IndID  Num1  Num2  Num3   Max
    #   <fct> <dbl> <dbl> <dbl> <dbl>
    # 1 AAA       1    NA     7     7
    # 2 BBB       2    NA    NA     2
    # 3 BBB       2     7     7     7
    # 4 BBB       2    NA    NA     2
    # 5 CCC       3     2     8     8
    # 6 CCC       3     5    NA     5
    # 7 DDD       4     8     7     8
    # 8 DDD       4     7    NA     7
    # 9 DDD       4     1     7     7
    #10 DDD       4     1     7     7
    

    如果这是获取按“IndID”分组的所有“Num”列的最大值,有多种方法。

    1) 从上面的步骤中,我们可以将其扩展为按'IndID'分组,然后取行最大值('Max')的max

    dat %>%        
        mutate(Max = pmax(!!! rlang::syms(names(.)[-1]), na.rm = TRUE)) %>% 
        group_by(IndID) %>% 
        mutate(Max = max(Max))
    

    2) 另一种选择是用gather将'wide'格式转换为'long',然后按'IndID'分组,得到'val'列的max和@ 987654330@与原始数据集

    library(tidyverse)
    gather(dat, key, val, -IndID) %>% 
        group_by(IndID) %>% 
        summarise(Max = max(val,na.rm = TRUE)) %>% 
        right_join(dat)
    

    3) 或者不重新整形为“长”格式的另一种选择是在按“IndID”、unlist 分组后的数据集nest 并获得“Num”的max ' 列

    dat %>%
       group_by(IndID) %>%
       nest %>%
       mutate(data =  map(data,  ~ .x %>% 
                                    mutate(Max = max(unlist(.), na.rm = TRUE)))) %>% 
       unnest
    

    【讨论】:

    • 与问题无关。 @akrun 如果你能看看我的回答here,给我反馈或者提出更好的建议,我将不胜感激。非常感谢。
    猜你喜欢
    • 2015-11-10
    • 2017-10-18
    • 1970-01-01
    • 2021-09-04
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 2011-06-27
    相关资源
    最近更新 更多