在具有分组数据的行和列中选择最大值

时间:2018-07-29 21:10:39

标签: r dplyr max

下面的数据具有一个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,其中包含Num1Num3的最大值。在大多数情况下,这涉及跨多个行和多个列查找最大值。在dplyr中,我错过了最后一步(如下),并且希望您提出任何建议。

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

1 个答案:

答案 0 :(得分:3)

可以选择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 '列和right_join和原始数据集

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

3)或不重塑为'long'格式的另一种方法是在按'IndID'nest分组后unlist收集数据集并获得{{1 }}的“数字”列

max