存储在变量中的 dplyr concat 列(变异和非标准评估)

dplyr concat columns stored in variable (mutate and non standard evaluation)

我想根据变量连接数据框中任意数量的列 cols_to_concat

df <- dplyr::data_frame(a = letters[1:3], b = letters[4:6], c = letters[7:9])
cols_to_concat = c("a", "b", "c")

要使用 cols_to_concat 这个特定值获得预期结果,我可以这样做:

df %>% 
  dplyr::mutate(concat = paste0(a, b, c))

但我需要概括一下,使用有点像这样的语法

# (DOES NOT WORK)
df %>% 
  dplyr::mutate(concat = paste0(cols))

我想使用 dplyr 0.7.0 的新 NSE approach,如果合适的话,但无法找出正确的语法。

您可以执行以下操作:

library(dplyr)

df <- dplyr::data_frame(a = letters[1:3], b = letters[4:6], c = letters[7:9])

cols_to_concat = lapply(list("a", "b", "c"), as.name)

q <- quos(paste0(!!! cols_to_concat))

df %>% 
  dplyr::mutate(concat = !!! q)

您可以尝试 syms 来自 rlang:

library(dplyr)
packageVersion('dplyr')
#[1] ‘0.7.0’
df <- dplyr::data_frame(a = letters[1:3], b = letters[4:6], c = letters[7:9])
cols_to_concat = c("a", "b", "c")

library(rlang)
cols_quo <- syms(cols_to_concat)
df %>% mutate(concat = paste0(!!!cols_quo))

# or
df %>% mutate(concat = paste0(!!!syms(cols_to_concat)))

# # A tibble: 3 x 4
#       a     b     c concat
#   <chr> <chr> <chr>  <chr>
# 1     a     d     g    adg
# 2     b     e     h    beh
# 3     c     f     i    cfi

如果您想坚持这些包和原则,您可以仅使用 tidyverse 执行此操作。您可以使用来自 tidyr 包的 mutate()unite_() 来完成。

使用mutate()

library(dplyr)
df <- tibble(a = letters[1:3], b = letters[4:6], c = letters[7:9])
cols_to_concat <- c("a", "b", "c")

df %>% mutate(new_col = do.call(paste0, .[cols_to_concat]))

# A tibble: 3 × 4
      a     b     c new_col
  <chr> <chr> <chr>   <chr>
1     a     d     g     adg
2     b     e     h     beh
3     c     f     i     cfi

使用unite_()

library(tidyr)
df %>% unite_(col='new_col', cols_to_concat, sep="", remove=FALSE)

# A tibble: 3 × 4
  new_col     a     b     c
*   <chr> <chr> <chr> <chr>
1     adg     a     d     g
2     beh     b     e     h
3     cfi     c     f     i

2020 年 7 月编辑

dplyr 1.0.0 开始,似乎 across()c_across() 正在替换下划线动词(例如 unite_)和范围变体,如 mutate_if()mutate_at()mutate_all()。下面是使用该约定的示例。不是最简洁的,但仍然是一个承诺更具可扩展性的选项。

使用c_across()

library(dplyr)

df <- tibble(a = letters[1:3], b = letters[4:6], c = letters[7:9])
cols_to_concat <- c("a", "b", "c")

df %>% 
  rowwise() %>% 
  mutate(new_col = paste0(c_across(all_of(cols_to_concat)), collapse=""))
#> # A tibble: 3 x 4
#> # Rowwise: 
#>   a     b     c     new_col
#>   <chr> <chr> <chr> <chr>  
#> 1 a     d     g     adg    
#> 2 b     e     h     beh    
#> 3 c     f     i     cfi

reprex package (v0.3.0)

于 2020-07-08 创建