我的数据框中有一列字符串,我试图将除n 个最常出现的字符串之外的所有字符串替换为“其他”。
尽管我目前的方法有效,但它似乎非常复杂,因为它涉及创建一个小标题并%in%用于创建一个布尔向量。
所以我的问题是:是否有更简单的方法使用dplyr来完成此操作,如果是这样,我将如何将其包装在一个函数中并使用 将其应用于多列mutate_all?
library(dplyr)
# setting up the data frame:
letter.df <- data_frame(val=sample(1:25, size = 100, replace = TRUE),
let=rep(x = letters[1:5], length.out=100))
letter.df[1:3, 2] <- c('x','y','z')
# my current approach more or less:
top5letters <- letter.df %>%
count(let) %>%
arrange(desc(n)) %>%
top_n(n=5)
idx <- letter.df$let %in% top5letters$let
letter.df$let[!idx] <- 'other'
Run Code Online (Sandbox Code Playgroud)
这个forcats包是tidyverse 的一部分,有一个函数fct_lump(),它(我认为)正是你想要的。
require(forcats)
letter.df %>%
mutate(let = fct_lump(let %>% as.factor, n=5))
Run Code Online (Sandbox Code Playgroud)
Forcats 是为因子设计的,因此对于您的示例数据,我必须将let列转换为因子而不是字符。如果你真的想让它说“其他”而不是“其他”,你可以这样做fct_lump(..., n=5, other_level='other')。
mutate_all()letter.df %>%
mutate_all(as.factor) %>%
mutate_all(~fct_lump(.x, n=5))
Run Code Online (Sandbox Code Playgroud)
由于fct_lump()已经是一个函数,所以很容易使用mutate_all()
如果您的数据太大并且转换为因子是瓶颈,我会建议您从问题中使用方法,但手动指定要保留的因子水平。这将让您一步完成“截断”和转换。
letter.df %>%
mutate(let = factor(let, levels=top5letters$let))
Run Code Online (Sandbox Code Playgroud)
(唯一的复杂性是NA您的原始数据中是否有您不想用 模糊的情况'other',因为最后一种方法会将所有未提供的级别转换为NA。)
有,但可能涉及right_join()。
letter.df %>%
count(let) %>%
arrange(desc(n)) %>%
top_n(n=5) %>%
right_join(letter.df, by = "let") %>%
mutate(let = ifelse(is.na(n), "other", let))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1311 次 |
| 最近记录: |