Назначение низких / средних / высоких меток в подгруппе на основе числового значения - PullRequest
1 голос
/ 28 января 2020

В настоящее время у меня есть таблица ниже.

Year   Value
2011   2.1
2011   2.1
2011   3.5
2011   7.8
2011   7.8
2012   1.8
2012   1.8
2012   1.8
2012   5.5

Я хочу классифицировать значения в пределах каждого "Года" так, чтобы метка low / med / high была назначена каждой строке на основе числового значения «Значение», т. е.

Year   Value  Cat
2011   2.1    Low
2011   2.1    Low
2011   3.5    Med
2011   7.8    High
2011   7.8    High
2012   1.8    Low
2012   1.8    Low
2012   1.8    Low
2012   5.5    High

Если в этом «году» есть 3 значения, то значения будут помечены как «Низкие», «Средние», «Высокие» в порядке возрастания. Если в «Годе» есть только 2 значения, метками будут только «Низкий» и «Высокий». Каждая подгруппа в «Годе» имеет только 2 или 3 различных значения.

Спасибо за помощь заранее.

Ответы [ 2 ]

2 голосов
/ 28 января 2020

Мы можем использовать dense_rank для получения порядка Value и использовать этот индекс для поднабора информации о категории.

library(dplyr)

df %>%
   group_by(Year) %>%
   mutate(Cat = if (n_distinct(Value) > 2)) 
                  c("Low", "Medium", "High")[dense_rank(Value)] else 
                  c("Low","High")[dense_rank(Value)])


#   Year Value Cat   
#  <int> <dbl> <chr> 
#1  2011   2.1 Low   
#2  2011   2.1 Low   
#3  2011   3.5 Medium
#4  2011   7.8 High  
#5  2011   7.8 High  
#6  2012   1.8 Low   
#7  2012   1.8 Low   
#8  2012   1.8 Low   
#9  2012   5.5 High

данные

df <- structure(list(Year = c(2011L, 2011L, 2011L, 2011L, 2011L, 2012L, 
2012L, 2012L, 2012L), Value = c(2.1, 2.1, 3.5, 7.8, 7.8, 1.8, 
1.8, 1.8, 5.5)), class = "data.frame", row.names = c(NA, -9L))
1 голос
/ 28 января 2020

Обновлено после изменения в наборе данных OP, а также только что заметил, что этот OP помечен dplyr. Отключится, если OP только ищет решение dplyr

Опция, использующая вывод data.table

DT[order(Year, Value), Cat := if(.N==1L) "L"
    else if(.N==2L) c("L", "H")[rleid(Value)]
    else c("L", "M", "H")[rleid(Value)], 
    Year]

:

    Year Value Cat
 1: 2011   2.1   L
 2: 2011   2.1   L
 3: 2011   3.5   M
 4: 2011   7.8   H
 5: 2011   7.8   H
 6: 2012   1.8   L
 7: 2012   1.8   L
 8: 2012   1.8   L
 9: 2012   5.5   M
10: 2013   1.0   L

данные:

library(data.table)
DT <- fread("Year   Value
2011   2.1
2011   2.1
2011   3.5
2011   7.8
2011   7.8
2012   1.8
2012   1.8
2012   1.8
2012   5.5
2013   1.0")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...