【问题标题】:Change multiple values in column in a tidyverse fashion以tidyverse方式更改列中的多个值
【发布时间】:2021-03-26 21:35:51
【问题描述】:

为了说明,让我们使用内置的 mpg 数据。

> mpg %>% select(model) %>% unique()
#   model             
#   <chr>             
# 1 a4                
# 2 a4 quattro        
# 3 a6 quattro  
# ...

我想将“a4 quattro”的所有值更改为“a4”,将“a6 quattro”更改为“a6”。我知道gsub

> mpg <- mpg %>% mutate(model = gsub("a4 quattro", "a4", model))
> mpg <- mpg %>% mutate(model = gsub("a6 quattro", "a6", model))

但是有没有办法让我在一行中做到这一点?

此外,有没有办法进一步概括这一点?假设我有一个带有结构的嵌套列表类型对象

> a
# $a4
# [1] "a4 quattro" "a4 model 2" "model 3"   
#
# $a6
# [1] "a6 quattro" "model k" 

是否有一种简单的方法可以将 mpg(我们的数据)中存在的 a$a4 中元素的所有实例更改为子列表“a4”的名称,并且对于 a$a6(以及可能更多的列表元素)的名称相同在一个)? 或者是否有“更好”的数据结构可用于此?

我希望以“tidyverse”的方式完成。 Purrr 功能还可以,但 for 循环不行。

提前致谢。

【问题讨论】:

  • 看看 tidyfast::dt_case_when()。此函数与 dplyr::case_when() 具有相同的语法,但建立在非常快的 data.table::fifelse() 之上。

标签: r list dplyr dataset


【解决方案1】:

您可以使用recode 进行完全匹配并将一个值替换为另一个值。

library(tidyverse)
mpg %>% 
   mutate(model = recode(model, 'a4 quattro' = 'a4', 'a6 quattro' = 'a6'))

也许如果你有像这里这样的模式,你可以使用一些正则表达式来实现所需的输出。

mpg %>% 
  mutate(model = sub(' quattro', '', model))

对于有限的值,您可以使用case_when

mpg %>%
  mutate(model = case_when(model %in% c("a4 quattro", "a4 model 2", "model 3") ~ 'a4', 
                           model %in% c("a6 quattro", "model k") ~'a6', 
                           TRUE ~ model))

如果您已经有一个列表,则可以将其转换为数据框并与原始数据连接,这是一种更通用的解决方案。

a <- list(a4 = c("a4 quattro", "a4 model 2", "model 3"), 
          a6 = c("a6 quattro", "model k"))

enframe(a) %>%
  unnest(value) %>%
  inner_join(mpg, by = c('value' = 'model'))

【讨论】:

    猜你喜欢
    • 2021-07-24
    • 2021-04-18
    • 2021-11-27
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    相关资源
    最近更新 更多