Объединение уровней фактора из кадра данных в R

У меня есть переменная типа factor с тремя уровнями: Fatal injury, Non-fatal injury а также P.D. only:

     head(OttawaCollisions$Collision_Classification)
[1] P.D. only        Non-fatal injury P.D. only        P.D. only        P.D. only        P.D. only       
Levels: Fatal injury Non-fatal injury P.D. only

Как я могу объединить "Смертельные травмы" и "Не смертельные травмы" в один уровень, чтобы смертельные случаи были добавлены к травмам?

А еще лучше, могу ли я как-то просто убить погибших? В этом случае мне нужно удалить каждый фатальный экземпляр из фрейма данных, а не просто закодированный NA или что-то еще.

2 ответа

Данные:

x <- factor( rep( c('P.D. only', 'Non-fatal injury' , 'fatal injury'), 2) )
x
# [1] P.D. only        Non-fatal injury fatal injury     P.D. only       
# [5] Non-fatal injury fatal injury    
# Levels: fatal injury Non-fatal injury P.D. only

Код: Вы можете переименовать уровень, используя labels аргумент. Игнорируйте предупреждение о дублированных уровнях. Вот Non-fatal injury а также fatal injury объединены вместе с Fatalities, Наконец, отбросьте дублированные уровни, используя droplevels() функция.

x <- factor( x = x, 
             levels = c('P.D. only', 'Non-fatal injury' , 'fatal injury'),
             labels = c('P.D. only', 'Fatalities', 'Fatalities'))
# [1] P.D. only  Fatalities Fatalities P.D. only  Fatalities Fatalities
# Levels: P.D. only Fatalities Fatalities

droplevels(x)
# [1] P.D. only  Fatalities Fatalities P.D. only  Fatalities Fatalities
# Levels: P.D. only Fatalities

РЕДАКТИРОВАТЬ: комбинированный код, основанный на вашем имени кадра данных

OttawaCollisions$CollisionClass <- factor( x = OttawaCollisions$CollisionClass, 
                                           levels = c('P.D. only', 'Non-fatal injury' , 'fatal injury'),
                                           labels = c('P.D. only', 'Fatalities', 'Fatalities'))
OttawaCollisions$CollisionClass <- droplevels(OttawaCollisions$CollisionClass)

EDIT2: data.table решение.

library('data.table')
setDT(OttawaCollisions)
OttawaCollisions[ i = CollisionClass %in% c( "fatal injury", "Non-fatal injury"), 
                  j = CollisionClass := "Fatalities"]
OttawaCollisions[, CollisionClass := droplevels(CollisionClass) ]

EDIT3: еще одно базовое решение R. Я бы предпочел это базовое решение R, а не первое (используя labels в factor()), потому что это облегчит жизнь, когда у вас будет больше уровней в данных.

OttawaCollisions$CollisionClass <- as.character(OttawaCollisions$CollisionClass)
OttawaCollisions$CollisionClass <- factor( with(OttawaCollisions, 
                                                replace( CollisionClass, 
                                                         CollisionClass %in% c( "fatal injury", "Non-fatal injury"),
                                                         "Fatalities") ) )

Вы также можете переназначить уровни напрямую:

> test_df <- tibble(x=as.factor(c('Fatal','Non-fatal','PD','Fatal','Non-fatal','PD')), y=1:6)
> test_df
# A tibble: 6 x 2
  x             y
  <fct>     <int>
1 Fatal         1
2 Non-fatal     2
3 PD            3
4 Fatal         4
5 Non-fatal     5
6 PD            6
> levels(test_df$x)
[1] "Fatal"     "Non-fatal" "PD"       

Теперь, когда вы знаете порядок, замените имена уровней, которые вы хотите объединить:

> levels(test_df$x) <- c("Fatal","Other","Other")
> test_df
# A tibble: 6 x 2
  x         y
  <fct> <int>
1 Fatal     1
2 Other     2
3 Other     3
4 Fatal     4
5 Other     5
6 Other     6

И тогда вы можете сделать дополнительную обработку, например:

> library(dplyr)
> test_df %>% group_by(x) %>% summarize(n)
# A tibble: 2 x 2
  x         n
  <fct> <dbl>
1 Fatal  45.0
2 Other  45.0
Другие вопросы по тегам