строка флага с максимальным числом в каждой строке - PullRequest
0 голосов
/ 08 июля 2020

вдохновленный этим вопросом , мне было интересно, как вы можете пометить строку с максимальным номером по группе, сохраняя при этом все остальные строки вместо их удаления?

Допустим, я хочу искать максимум в Value для каждого ID отдельно. Затем отметьте максимальную строку с помощью 1, а все остальные - с помощью 0.

, поэтому в основном получаем от этого:

ID    <- c(1,1,1,2,2,2,2,3,3)
Value <- c(2,3,5,2,5,8,17,3,5)
Event <- c(1,1,2,1,2,1,2,2,2)
DF <- data.table(cbind(ID, Value, Event))
DF
   ID Value Event
1:  1     2     1
2:  1     3     1
3:  1     5     2
4:  2     2     1
5:  2     5     2
6:  2     8     1
7:  2    17     2
8:  3     3     2
9:  3     5     2

до этого:

DF
   ID Value Event flagMAX
1:  1     2     1       0
2:  1     3     1       0
3:  1     5     2       1
4:  2     2     1       0
5:  2     5     2       0
6:  2     8     1       1
7:  2    17     2       1
8:  3     3     2       0
9:  3     5     2       0

как это можно сделать? в идеале с data.table

я пробовал:

DF[,flagMAX := ifelse(max(Value), 1, 0), by = "ID"]

, но получил все 1

любые идеи?

Ответы [ 2 ]

0 голосов
/ 08 июля 2020

С помощью data.table мы можем сгруппировать по «ID», преобразовать логический вектор в двоичный с помощью (as.integer или +) и назначить (:=) вывод для создания нового столбца 'flagMAX'

library(data.table)
DF[, flagMAX := +(Value == max(Value)), ID]

Если мы группируем как по идентификатору, так и по событию

DF[, flagMAX := +(Value == max(Value)), by = .(ID, Event)]

В коде OP аргумент ifelse 'test' не является логическим вектором, а является единственным числовым c значением из max(Value), это приводит к логическому преобразованию, в результате чего любое значение больше 0 становится ИСТИНА и другие ЛОЖЬ. Таким образом, в результате получается 1

Иллюстрация ниже

DF[, max(Value), ID]
#   ID V1
#1:  1  5
#2:  2 17
#3:  3  5

Теперь мы приводим его к логическому

DF[, as.logical(max(Value)), ID]
#   ID   V1
#1:  1 TRUE
#2:  2 TRUE
#3:  3 TRUE

Когда мы выполняем присваивание с помощью ifelse(TRUE, 1, 0), оно возвращает все единицы. Если у нас есть максимальное значение 0, возвращается FALSE

as.logical(c(5, 17, 5, 0))
#[1]  TRUE  TRUE  TRUE FALSE
0 голосов
/ 08 июля 2020

Если вы принимаете ответ с tidyverse

library(tidyverse)

ID    <- c(1,1,1,2,2,2,2,3,3)
Value <- c(2,3,5,2,5,8,17,3,5)
Event <- c(1,1,2,1,2,1,2,2,2)
DF <- data.frame(cbind(ID, Value, Event))

DF %>% 
  group_by(ID) %>% 
  mutate(flag = ifelse(Value == max(Value), 1,0))
#> # A tibble: 9 x 4
#> # Groups:   ID [3]
#>      ID Value Event  flag
#>   <dbl> <dbl> <dbl> <dbl>
#> 1     1     2     1     0
#> 2     1     3     1     0
#> 3     1     5     2     1
#> 4     2     2     1     0
#> 5     2     5     2     0
#> 6     2     8     1     0
#> 7     2    17     2     1
#> 8     3     3     2     0
#> 9     3     5     2     1
...