Коэффициент сосредоточения на основе другого столбца

В этом примере показаны измерения объема производства различных фабрик, где первые столбцы обозначают фабрику, а последний столбец - произведенное количество.

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]
Другие вопросы по тегам