Коэффициент сосредоточения на основе другого столбца
В этом примере показаны измерения объема производства различных фабрик, где первые столбцы обозначают фабрику, а последний столбец - произведенное количество.
factory <- c("A","A","B","B","B","B","B","C","D")
production <- c(15, 2, 1, 1, 2, 1, 2,20,5)
df <- data.frame(factory, production)
df
factory production
1 A 15
2 A 2
3 B 1
4 B 1
5 B 2
6 B 1
7 B 2
8 C 20
9 D 5
Теперь я хочу объединить фабрики на меньшее количество уровней, основываясь на их общем выходе в этом наборе данных.
Используя обычные forcats::fct_lump, я могу объединить их по количеству строк, в которых они появляются, например, для создания 3 уровней:
library(tidyverse)
df %>% mutate(factory=fct_lump(factory,2))
factory production
1 A 15
2 A 2
3 B 1
4 B 1
5 B 2
6 B 1
7 B 2
8 Other 20
9 Other 5
но я хочу объединить их на основе суммы (производства), сохранив лучшие n=2 фабрики (по общему объему производства) и сложив оставшиеся фабрики. Желаемый результат:
1 A 15
2 A 2
3 Other 1
4 Other 1
5 Other 2
6 Other 1
7 Other 2
8 C 20
9 Other 5
Какие-либо предложения?
Спасибо!
3 ответа
Ключевым моментом здесь является применение определенной философии для группировки заводов на основе их суммы производства. Обратите внимание, что эта философия связана с фактическими значениями, имеющимися в вашем (реальном) наборе данных.
Опция 1
Вот пример, который объединяет фабрики, у которых суммарная продукция равна 15 или меньше. Если вы хотите другую группу, вы можете изменить порог (например, использовать 18 вместо 15)
factory <- c("A","A","B","B","B","B","B","C","D")
production <- c(15, 2, 1, 1, 2, 1, 2,20,5)
df <- data.frame(factory, production, stringsAsFactors = F)
library(dplyr)
df %>%
group_by(factory) %>%
mutate(factory_new = ifelse(sum(production) > 15, factory, "Other")) %>%
ungroup()
# # A tibble: 9 x 3
# factory production factory_new
# <chr> <dbl> <chr>
# 1 A 15 A
# 2 A 2 A
# 3 B 1 Other
# 4 B 1 Other
# 5 B 2 Other
# 6 B 1 Other
# 7 B 2 Other
# 8 C 20 C
# 9 D 5 Other
Я создаю factory_new
без удаления (оригинал) factory
колонка.
Вариант 2
Вот пример, в котором вы можете ранжировать / упорядочивать фабрики в зависимости от их производства, а затем вы можете выбрать несколько ведущих фабрик, чтобы они остались такими, как есть, и сгруппировать остальные.
factory <- c("A","A","B","B","B","B","B","C","D")
production <- c(15, 2, 1, 1, 2, 1, 2,20,5)
df <- data.frame(factory, production, stringsAsFactors = F)
library(dplyr)
# get ranked factories based on sum production
df %>%
group_by(factory) %>%
summarise(SumProd = sum(production)) %>%
arrange(desc(SumProd)) %>%
pull(factory) -> vec_top_factories
# input how many top factories you want to keep
# rest will be grouped together
n = 2
# apply the grouping based on n provided
df %>%
group_by(factory) %>%
mutate(factory_new = ifelse(factory %in% vec_top_factories[1:n], factory, "Other")) %>%
ungroup()
# # A tibble: 9 x 3
# factory production factory_new
# <chr> <dbl> <chr>
# 1 A 15 A
# 2 A 2 A
# 3 B 1 Other
# 4 B 1 Other
# 5 B 2 Other
# 6 B 1 Other
# 7 B 2 Other
# 8 C 20 C
# 9 D 5 Other
Просто укажите аргумент веса
w
:
> df %>%
+ mutate(factory = fct_lump_n(factory, 2, w = production))
factory production
1 A 15
2 A 2
3 Other 1
4 Other 1
5 Other 2
6 Other 1
7 Other 2
8 C 20
9 Other 5
Примечание: используйте
forcats::fct_lump_n
потому что общий
fct_lump
больше не рекомендуется.
Мы могли бы использовать base R
а также путем создания логического условия с ave
df$factory_new <- "Other"
i1 <- with(df, ave(production, factory, FUN = sum) > 15)
df$factory_new[i1] <- df$factory[i1]