【问题标题】:Keeping original variables with dplyr::mutate_at & varying length of dynamic variables使用 dplyr::mutate_at 和不同长度的动态变量保留原始变量
【发布时间】:2019-01-15 05:54:51
【问题描述】:

我遇到了一个出色的 SO 帖子/答案 here,它表明可以使用 dplyr::mutate_at 保留原始变量,而使用用户定义的后缀创建新变量。代码运行如下:

library(tidyverse)
dataframe <- data_frame(
  helloo = c(1, 2, 3, 4, 5, 6),
  ooooHH = c(1, 1, 1, 2, 2, 2),
  ahaaa = c(200, 400, 120, 300, 100, 100)
)

dataframe %>%
  mutate_at(
    vars(contains("oo")),
    .funs = funs(cat = ntile(., 2))
  )

产生

# A tibble: 3 x 5
  helloo ooooHH ahaaa helloo_cat ooooHH_cat
   <dbl>  <dbl> <dbl>      <int>      <int>
1      1      1   200          1          1
2      2      1   400          1          1
3      3      1   120          2          2

但是,如果vars只有一个变量,那么这个后缀方案就不能像上面那样工作:例如:

varlist <- c('ooooHH')
dataframe %>% 
  mutate_at(
    vars(varlist), 
    .funs = funs(cat = ntile(., 2))
  )

产生输出为

# A tibble: 3 x 4
  helloo ooooHH ahaaa   cat
   <dbl>  <dbl> <dbl> <int>
1      1      1   200     1
2      2      1   400     1
3      3      1   120     2

我明白道理---如果只有一个变量发生突变,则无需区分新变量。但是,为了保持一致性,我希望将 cat 列命名为 ooooHH_cat,因为我将多次执行此操作,并且进入 vars 的动态列名称的长度会有所不同。另外,我希望保留结果以供何时使用

varlist <- c('helloo', 'ooooHH')

有什么建议吗?

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    编辑

    由于字符串存在于变量中,我们无法对其进行硬编码。

    varlist <- c('helloo', 'ooooHH')
    

    我们可以修改函数来重命名varlist对象。

    dataframe %>% 
      mutate_at(
      vars(varlist), 
       .funs = funs(cat = ntile(., 2))
     ) %>%
    rename_at(vars(grep("^cat$", names(.))), 
              funs(sub("cat", paste0(varlist, "_cat"), .))) 
    

    原答案

    只有当我们找到“猫”的完全匹配时,才能使用rename_at 替换同一链接的黑客方法

    library(dplyr)
    dataframe %>% 
      mutate_at(
        vars('ooooHH'), 
        .funs = funs(cat = ntile(., 2))
       ) %>%
    rename_at(vars(grep("^cat$", names(.))), funs(sub("cat", "ooooHH_cat", .))) 
    
    #   helloo ooooHH ahaaa ooooHH_cat
    #   <dbl>  <dbl> <dbl>      <int>
    #1   1.00   1.00   200          1
    #2   2.00   1.00   400          1
    #3   3.00   1.00   120          1
    #4   4.00   2.00   300          2
    #5   5.00   2.00   100          2
    #6   6.00   2.00   100          2
    

    当有多个列并且已经应用​​了重命名时,它不会影响。

    dataframe %>%
       mutate_at(
       vars(contains("oo")),
        .funs = funs(cat = ntile(., 2))
      ) %>%
     rename_at(vars(grep("^cat$", names(.))), funs(sub("cat", "ooh_cat", .))) 
    
    
    #   helloo ooooHH ahaaa helloo_cat ooooHH_cat
    #   <dbl>  <dbl> <dbl>      <int>      <int>
    #1   1.00   1.00   200          1          1
    #2   2.00   1.00   400          1          1
    #3   3.00   1.00   120          1          1
    #4   4.00   2.00   300          2          2
    #5   5.00   2.00   100          2          2
    #6   6.00   2.00   100          2          2
    

    【讨论】:

    • 一件事---假设'ooooHH'作为列名的一般向量输入到函数中---例如,varlist &lt;- c('ooooHH')将用作vars(varlist)。所以我不想为sub 使用精确的字符。我该怎么办?
    • @Kim 在这种情况下,dataframe %&gt;% mutate_at( vars(varlist), .funs = funs(cat = ntile(., 2)) ) %&gt;% rename_at(vars(grep("^cat$", names(.))), funs(sub("cat", paste0(varlist, "_cat"), .))) 怎么样?
    • varlist &lt;- c('ooooHH', 'helloo') 时,这似乎不太有效,就是这样。 :(
    • @Kim 它似乎工作正常吗?它只是给出警告,但我认为可以忽略,因为它永远不会到达varlist 中多个元素的代码部分。它只会在找到与“cat”完全匹配时更改列名。
    • 啊哈,我一定是搞错了什么——你是对的。我可以忽略警告。非常感谢!
    猜你喜欢
    • 2018-02-07
    • 1970-01-01
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 2019-04-03
    相关资源
    最近更新 更多