重命名分类级别以减少级别数

时间:2019-12-22 12:39:42

标签: r

我有一个分类列,该列在大约78000条记录的数据集中具有大约1200个级别。我想根据发生次数降低水平。例如。 -:

  • 发生超过2000次的所有级别都重命名为“ A”。
  • 发生的所有级别大于1000次但小于2000次 重命名为“ B”
  • 发生的所有级别大于900次但小于1000次 重命名为“ C”

以此类推。

我不想将发生频率较低的级别归为“其他”,因为这样会隐藏许多重要级别。
例如,下面是数据框。

df=data.frame(
  ID = c(1:10),
  Name = c("Jack", "Mike","Jack", "Mike","Jack", "Mike", "Tom", "Tom", "Smith", "Tony")
)

在这里,我想通过以下方式减少“名称”列的级别:

  • 将出现的所有级别重命名为A的次数大于等于3次
  • 重命名出现的所有级别> = 2,但<3倍为“ B”
  • 将所有<2次出现的关卡重命名为“ C”

有人可以帮助我在R中做到这一点吗?

3 个答案:

答案 0 :(得分:2)

我们可以使用add_count来计数Name的实例,然后使用case_when检查条件

library(dplyr)

df %>% 
  add_count(Name) %>%
  mutate(NewName = case_when(n >= 3 ~'A', 
                             n >= 2 & n < 3 ~'B', 
                             TRUE ~'C')) %>%
  select(-n, -Name)

#     ID NewName
#   <int> <chr>  
# 1     1 A      
# 2     2 A      
# 3     3 A      
# 4     4 A      
# 5     5 A      
# 6     6 A      
# 7     7 B      
# 8     8 B      
# 9     9 C      
#10    10 C      

答案 1 :(得分:2)

使用table

的基本R解决方案
NameCount = table(df$Name)[df$Name]
NewName = rep("C", length(NameCount))
NewName[NameCount >= 2] = "B"
NewName[NameCount >= 3] = "A"
NewName
 [1] "A" "A" "A" "A" "A" "A" "B" "B" "C" "C"

答案 2 :(得分:0)

我们可以使用fcasedata.table)的开发版本中的1.12.9,它也会懒惰地进行评估

library(data.table)
setDT(df)[, NewName := fcase(.N >=3, 'A',
                             .N >=2 & .N < 3, 'B',
                             default = 'C'), Name][]
#    ID  Name NewName
# 1:  1  Jack       A
# 2:  2  Mike       A
# 3:  3  Jack       A
# 4:  4  Mike       A
# 5:  5  Jack       A
# 6:  6  Mike       A
# 7:  7   Tom       B
# 8:  8   Tom       B
# 9:  9 Smith       C
#10: 10  Tony       C

或将base RfindInterval一起使用

with(df, rev(LETTERS[1:3])[findInterval(table(Name)[Name], 2:3) + 1])
#[1] "A" "A" "A" "A" "A" "A" "B" "B" "C" "C"