【问题标题】:Purrr map with rename_with带有 rename_with 的 Purrr 地图
【发布时间】:2020-12-23 01:15:28
【问题描述】:

我正在尝试清理数据集的名称。我用janitor::clean_names() 开始。但是,我仍然有一些缩写,我想用下划线 _ 分开。我有使用rename_with(~str_replace(.x, "gh", "gh_"), .cols = starts_with("gh")) 的代码,但是有很多缩写,最好找到map 的方法或以其他方式功能化此过程。

dat <- tibble(ghrisk_value = c(1,2), 
              ghrisk_corrected = c(2,3), 
              devpolicy_value = c(4,5),
              devpolicy_corrected = c(5,6))

# code works but not functionalized
dat %>%
   rename_with(~str_replace(.x, "gh", "gh_"), .cols = starts_with("gh")) %>%
   rename_with(~str_replace(.x, "dev", "dev_"), .cols = starts_with("dev")) %>%
   names()

# attempt at map...
abbr_words <- c("gh", "dev")
map(dat, ~rename_with(str_replace(.x, abbr_words, str_c(abbr_words, "_"))) 

【问题讨论】:

    标签: r tidyverse purrr stringr


    【解决方案1】:

    使用地图,您将需要一个辅助函数,即 real_func。 map 将适用于 colnames(dat),并且一次只能使用一个 colname。 Map需要一个函数real_func,第一个参数,即数据参数将在函数之前,其余参数将在函数之后。 Repl_func 将一次获取一个列名并获取缩写词列表,循环遍历它并执行替换。在 unlist 结束时,需要返回一个扁平化的向量。

    abbr_words <- c("gh", "dev")
    
    repl_func <- function(x,y){
      for (i in y){
        x <- str_replace(x,i,paste0(i,"_"))
      }
      return (x)
    }
    
    
    colnames(dat) <- unlist(map(colnames(dat), repl_func, abbr_words))
    

    【讨论】:

      【解决方案2】:

      您可以将reduce 上面的单词替换为str_replace

      abbr_words <- c("gh", "dev")
      
      dat %>% 
        rename_all( ~
          reduce(abbr_words, ~str_replace(.x, paste0('^', .y), paste0(.y, '_')), .init = names(dat))
        )
      
      # # A tibble: 2 x 4
      #   gh_risk_value gh_risk_corrected dev_policy_value dev_policy_corrected
      #           <dbl>             <dbl>            <dbl>                <dbl>
      # 1             1                 2                4                    5
      # 2             2                 3                5                    6
      

      【讨论】:

        【解决方案3】:

        您不需要map()。只需使用正则表达式语法"(?&lt;=a|b|c)",它匹配abc 后面的位置并插入下划线。另外starts_with()可以将一个字符向量作为输入来匹配所有元素的并集。

        abbr_words <- c("gh", "dev")
        
        pattern <- sprintf("(?<=%s)", str_c(abbr_words, collapse = "|"))
        # [1] "(?<=gh|dev)"
        
        dat %>%
          rename_with(~ str_replace(.x, pattern, "_"), starts_with(abbr_words))
        
        # # A tibble: 2 x 4
        #   gh_risk_value gh_risk_corrected dev_policy_value dev_policy_corrected
        #           <dbl>             <dbl>            <dbl>                <dbl>
        # 1             1                 2                4                    5
        # 2             2                 3                5                    6
        

        【讨论】:

        • 谢谢!如果我想匹配这些单词之后的位置,正则表达式将是:"(%s=&gt;?)"?
        • @Nick “匹配这些词之后的位置”与我在回答中提到的含义相同。你真的想在哪里匹配?
        • 抱歉,可能打错了。如果我想在单词之前而不是之后加下划线,我会这样做吗?
        • @Nick Try "(?=%s)".
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-11
        • 1970-01-01
        • 2021-10-26
        • 1970-01-01
        • 2019-12-27
        • 1970-01-01
        • 2019-01-18
        相关资源
        最近更新 更多