如何使用整洁的评估语义选择,复制和重命名多个列?

时间:2017-10-24 17:17:56

标签: r tidyverse nse

我想在我的tibble中复制一组变量,这样我可以在下游评估中获得variable_unmodifiedvariable值。我使用旧式下划线NSE select_()函数和.dots提出了一个hacky版本,但是想使用更新的NSE方法来进行整洁的评估语义。

这就是我想要的:

tibble_to_max <- tibble(
  "a_col" = c("1", "2", "3", "4"),
  "max_1" = c("3;4", "2{3}4", "7", ".{1}"),
  "max_2" = c("3;4", "2{3}4", "7", ".{1}")
)

cols_to_max <- c("max_1", "max_2")

unparsed_names <-  paste0(cols_to_max, "_unparsed")

tibble_to_max %>%
  bind_cols(select_(., .dots = setNames(cols_to_max, unparsed_names)))

输出:

# A tibble: 4 x 5
  a_col max_1 max_2 max_1_unparsed max_2_unparsed
  <chr> <chr> <chr>          <chr>          <chr>
1     1   3;4   3;4            3;4            3;4
2     2 2{3}4 2{3}4          2{3}4          2{3}4
3     3     7     7              7              7
4     4  .{1}  .{1}           .{1}           .{1}

但如果我尝试使用select()!!.dots无法正常工作:

tibble_to_max %>%
  bind_cols(select(., .dots = setNames(!!cols_to_max, !!unparsed_names)))

列未按要求命名:

# A tibble: 4 x 5
  a_col max_1 max_2 .dots1 .dots2
  <chr> <chr> <chr>  <chr>  <chr>
1     1   3;4   3;4    3;4    3;4
2     2 2{3}4 2{3}4  2{3}4  2{3}4
3     3     7     7      7      7
4     4  .{1}  .{1}   .{1}   .{1}

这样做的正确方法是什么?另外,避免将unparsed_names定义为单独的变量的奖励积分......

2 个答案:

答案 0 :(得分:1)

也许是这样的

您的数据

tibble_to_max <- tibble(
  "a_col" = c("1", "2", "3", "4"),
  "max_1" = c("3;4", "2{3}4", "7", ".{1}"),
  "max_2" = c("3;4", "2{3}4", "7", ".{1}")
)

使用nest的解决方案,然后一次复制嵌套数据,然后复制unnest。我使用rename_all重命名data_copy

中的列
library(tidyverse)
tibble_to_max %>%
  nest(-a_col) %>%
  mutate(data_copy = data) %>%
  mutate(data_copy = map(data_copy, ~.x %>% rename_all(funs(paste0(., "_unparsed"))))) %>% 
  unnest(data, data_copy)

输出

# A tibble: 4 x 5
  a_col max_1 max_2 max_1_unparsed max_2_unparsed
  <chr> <chr> <chr>          <chr>          <chr>
1     1   3;4   3;4            3;4            3;4
2     2 2{3}4 2{3}4          2{3}4          2{3}4
3     3     7     7              7              7
4     4  .{1}  .{1}           .{1}           .{1}

答案 1 :(得分:0)

感谢@CPak让我走上了正确的道路。这完成了我拍摄的内容,并使用整齐的评估语义而不是select_()

tibble_to_max <- tibble(
  "a_col" = c("1", "2", "3", "4"),
  "max_1" = c("3;4", "2{3}4", "7", ".{1}"),
  "max_2" = c("3;4", "2{3}4", "7", ".{1}")
)

cols_to_max <- c("max_1", "max_2")

tibble_to_max %>%
  bind_cols(
    select_at(., 
      .vars = !!cols_to_max, 
      .funs = funs(paste0(., "_unparsed"))
      )
    )