【问题标题】:Passing names of objects from ellipsis as strings to left_join将省略号中的对象名称作为字符串传递给 left_join
【发布时间】:2020-06-26 22:27:43
【问题描述】:

背景

我有一个简单的辅助函数,它将left_join 应用于gather 之外的任意数量的传递表并返回一个对象。

示例

# Settings ----------------------------------------------------------------

library("tidyverse")
set.seed(123)

# Data --------------------------------------------------------------------

sample_one <-
    tibble(
        column_a = c(1, 2),
        column_b = runif(n = 2),
        column_other = runif(n = 2)
    )
sample_two <-
    tibble(
        column_a = c(1, 2),
        column_b = runif(n = 2),
        column_other = runif(n = 2)
    )
sample_three <-
    tibble(
        column_a = c(1, 2),
        column_b = runif(n = 2),
        column_other = runif(n = 2)
    )

# Function ----------------------------------------------------------------

left_join_on_column_a <- function(keep_var, ...) {
    keep_var <- enquo(keep_var)
    dots <- list(...)
    clean_dfs <- map(dots, select, !!keep_var, "column_a")
    reduce(.x = clean_dfs,
           .f = left_join,
           "column_a") %>%
        gather(key = "model_type", !!keep_var, -column_a)
}

# Test --------------------------------------------------------------------

left_join_on_column_a(keep_var = column_b, sample_one, sample_two, sample_three)

问题

我希望能够以编程方式修改 left_joinsuffix 参数:

后缀 如果 x 和 y 中存在未连接的重复变量,则这些 后缀将被添加到输出中以消除它们的歧义。应该是一个 长度为 2 的字符向量。

当前结果

# A tibble: 6 x 3
  column_a model_type column_b
     <dbl> <chr>         <dbl>
1        1 column_b.x   0.288 
2        2 column_b.x   0.788 
3        1 column_b.y   0.940 
4        2 column_b.y   0.0456
5        1 column_b     0.551 
6        2 column_b     0.457 

期望的结果

# A tibble: 6 x 3
  column_a model_type      column_b
     <dbl> <chr>            <dbl>
1        1 sample_one       0.288 
2        2 sample_one       0.788 
3        1 sample_two       0.940 
4        2 sample_two       0.0456
5        1 sample_three     0.551 
6        2 sample_three     0.457 

model_type 列反映了通过... 传递的对象的名称。

尝试

我试图捕获在 ... 中传递的对象的名称,但它不是命名对象,因此没有意义:

left_join_on_column_a <- function(keep_var, ...) {
    keep_var <- enquo(keep_var)
    dots <- list(...)
    table_names <- names(dots)
    clean_dfs <- map(dots, select, !!keep_var, "column_a")
    reduce(.x = clean_dfs,
           .f = left_join,
           "column_a", 
           table_names) %>%
        gather(key = "model_type", !!keep_var, -column_a)
}

【问题讨论】:

    标签: r left-join tidyverse ellipsis tidyeval


    【解决方案1】:

    也许重命名column_b 这样你就不用担心后缀了

    left_join_on_column_a <- function(keep_var, common_var, ...) {
        nm = unname(sapply(rlang::enexprs(...), as.character))
        keep_var <- as.character(substitute(keep_var))
        common_var = as.character(substitute(common_var))
    
        foo = function(x, y) {
            x %>% select(!!common_var, !!y := !!keep_var)
        }
    
        reduce(.x = Map(foo, list(...), nm),
               .f = left_join,
               common_var) %>%
            gather("model_type", !!keep_var, -!!common_var)
    }
    
    left_join_on_column_a(column_b, column_a, sample_one, sample_two, sample_three)
    

    【讨论】:

    • 这是个好主意,尤其是nm = unname(sapply(rlang::enexprs(...), as.character))
    猜你喜欢
    • 1970-01-01
    • 2016-12-05
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多