使用mutate(dplyr)将列名的向量传递给paste()。

4
我正在尝试编写一个函数,其中一个参数是用户提供的列名向量。这些列名将用于指定哪些数据框的列将被粘贴在一起形成一个新的列,以在dplyr :: mutate中使用。我尝试先折叠参数向量的元素,然后在mutate中使用折叠的字符串 - 这是错误的。请参见下面的最新尝试。我做过其他尝试,但我不理解dplyr中的新quo,enquo,UQ,!!!,!!等内容。有人可以展示我需要做什么吗?
df <- data.frame(.yr = c("2000", "2001", "2002"), .mo = c("12", "01", "02"), .other = rnorm(3))
cols <- colnames(df)[1:2]

do_want <- df %>%
  mutate(new = paste(.yr, .mo, sep = "-"))

my_func <- function(dat, vars){
  .vars <- paste(vars, collapse = ",")

  result <- dat %>%
    mutate(new = paste(.vars, sep = "-" ))
  return(result)
}

my_func(dat = df, vars = cols)

编辑:这是我尝试在函数定义中使用quo和!!的结果。结果是一个重复字符串“.yr,.mo”的列。

my_func <- function(dat, vars){
  .vars <- quo(paste(vars, collapse = ","))

  result <- dat %>%
    mutate(new = paste(!!.vars, sep = "-" ))
  return(result)
}
3个回答

9

因为您有一个字符串列表,所以在函数中可以使用rlang::syms将字符串转换成符号。然后您可以使用!!!来拼接参数并放入paste中。

my_func <- function(dat, vars){
     .vars <- rlang::syms(vars)

     result <- dat %>%
          mutate(new = paste(!!!.vars, sep = "-" ))
     return(result)
}

my_func(dat = df, vars = cols)

   .yr .mo     .other     new
1 2000  12 -0.2663456 2000-12
2 2001  01  0.5463433 2001-01
3 2002  02 -1.3133078 2002-02

@Jelena-bioinf 如果你想使用dplyr编程,我不知道如何避免感叹号。如果你还没有看过,请参见这里。但是,如果你在dplyr之外工作或者不编写函数,那么你肯定可以避免使用感叹号! - aosmith
是的,当在函数外部工作时,“dplyr”非常美丽。但是当您需要以基于函数的方式执行操作时,它会失去一致性和优雅。 - JelenaČuklina

1
使用 unite。
names <- iris %>% colnames()
iris %>% mutate(new = paste(names)) #Error
iris %>% unite("new",names,remove=F) #OK

0
使用mutate_替代mutate,并将表达式转换为字符串对我有用:
dplyr_solution <- function(dat, vars){
  .vars <- paste(vars, collapse = ",")

  result <- dat %>%
    mutate_(new = paste0('paste(', .vars, ', sep="-")'))
  return(result)
}

dplyr_solution(dat = df, vars = cols)

谢谢 - 我尝试过这样的方法,但没有将内部粘贴包含在引号中。这个方法有效,仍然希望有人能展示一种利用新的rLang功能的解决方案,这使得mutate_变得多余,并且比三个嵌套的粘贴更优雅。 - bikeactuary
3
现在,在dplyr中,"mutate_"等函数已被弃用。 - GcL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接