Объединение уровней фактора из кадра данных в 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