代码之家  ›  专栏  ›  技术社区  ›  Kim

使用dplyr::mutate_保留原始变量并改变动态变量的长度

  •  1
  • Kim  · 技术社区  · 8 年前

    我遇到了一个非常好的所以帖子/答案 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 为了保持一致性,因为我将多次执行此操作,以及 瓦尔斯 长度不同。另外,我希望在什么时候保存结果

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

    有什么建议吗?

    1 回复  |  直到 8 年前
        1
  •  1
  •   Ronak Shah    8 年前

    编辑

    因为字符串存在于变量中,所以我们不能硬编码它。

    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 只有当我们找到与“cat”完全匹配时才更换

    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