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

时间:2018-08-08 04:34:55

标签: r dplyr tidyverse

我遇到了一篇出色的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')

有什么建议吗?

1 个答案:

答案 0 :(得分: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"), .))) 

原始答案

只有当我们找到与“ 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