Получите максимальное значение по категориям в виде нового столбца в R

#r #dplyr #tidyverse

Вопрос:

Я понимаю, что формулировка вопросов неясна, но она проста, надеюсь, изображение передаст больше, чем слова. Мне нужен новый столбец (Новый столбец на изображении), который получает значение из столбца B, соответствующее максимальному значению в столбце N (по группам) в данном случае A.

Предпочтительно решение tidyverse, так как я передаю длинную команду.

    df <-  structure(list(A = c("a", "a", "a", "a", "a", "b", "b", "b"), 
        B = c("b", "c", "d", "e", "f", "c", "d", "e"), N = c(1L, 
        2L, 3L, 4L, 5L, 5L, 4L, 3L), New.Col = c("f", "f", "f", "f", 
        "f", "c", "c", "c")), class = "data.frame", row.names = c(NA, 
    -8L))
 

Выход

Ответ №1:

Вот чистая и аккуратная версия моего ответа без ifelse :

 library(dplyr)

df %>% 
  group_by(A) %>% 
  mutate(new_col = B[N==max(N)]) 

  A     B         N New.Col new_col
  <chr> <chr> <int> <chr>   <chr>  
1 a     b         1 f       f      
2 a     c         2 f       f      
3 a     d         3 f       f      
4 a     e         4 f       f      
5 a     f         5 f       f      
6 b     c         5 c       c      
7 b     d         4 c       c      
8 b     e         3 c       c  
 

Первый ответ:
Мы могли бы использовать max в ifelse заявлении:

 library(dplyr)
df %>%
  group_by(A) %>% 
  mutate(NewCol = ifelse(N==max(N), B, B)) %>% 
  select(-NewCol)
 
   A     B         N New.Col
  <chr> <chr> <int> <chr>  
1 a     b         1 f      
2 a     c         2 f      
3 a     d         3 f      
4 a     e         4 f      
5 a     f         5 f      
6 b     c         5 c      
7 b     d         4 c      
8 b     e         3 c 
 

Ответ №2:

С помощью data.table

 library(data.table)
 setDT(df)[, new_col := B[which.max(N)], A]
> df
   A B N New.Col new_col
1: a b 1       f       f
2: a c 2       f       f
3: a d 3       f       f
4: a e 4       f       f
5: a f 5       f       f
6: b c 5       c       c
7: b d 4       c       c
8: b e 3       c       c
 

Ответ №3:

Вы можете просто использовать обычный group_by и mutate

 library(tidyverse)

df <-  structure(list(A = c("a", "a", "a", "a", "a", "b", "b", "b"), 
                      B = c("b", "c", "d", "e", "f", "c", "d", "e"), N = c(1L, 
                                                                           2L, 3L, 4L, 5L, 5L, 4L, 3L), New.Col = c("f", "f", "f", "f", 
                                                                                                                    "f", "c", "c", "c")), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                              -8L))

df %>% 
  group_by(A) %>% 
  mutate(new_col = B[which.max(N)]) %>% 
  ungroup()