如何使用环境变量执行dplyr连接

dgenwo3n  于 2023-02-10  发布在  其他
关注(0)|答案(2)|浏览(125)

我依赖于https://dplyr.tidyverse.org/articles/programming.html来创建交互式的整洁函数,这些函数依赖于环境变量(本文就是这样称呼它们的),例如下面的例子。

var_summary <- function(data, var) {
  data %>%
    summarise(n = n(), min = min({{ var }}), max = max({{ var }}))
}
mtcars %>% 
  group_by(cyl) %>% 
  var_summary(mpg)
#> `summarise()` ungrouping output (override with `.groups` argument)

然而,当我尝试使用left_join()的类似方法时,我收到了一个错误。

# A table
foobar <- tribble(~fooname, ~value, "setosa", 20, "versicolor", 30, "virginica", 10)

# A function
foobarjoin <- function(table, joincol){iris %>% left_join(table, by = c("Species" = {{ joincol }}))}

# When I use the function
 foobarjoin(table = foobar, joincol = fooname)

#> Error in standardise_join_by(by, x_names = x_names, y_names = y_names) : 
#>  object 'fooname' not found

使用环境变量在自定义函数中执行dplyr连接的正确方法是什么?

注意这不是How to join (merge) data frames (inner, outer, left, right)的重复问题。那个问题是一个vanilla join问题。这个问题是关于如何在函数中使用环境变量来实现join的。

blmhpbnm

blmhpbnm1#

left_join或连接通常需要字符值。因此,请将函数更改为:

library(dplyr)
foobarjoin <- function(table, joincol) {
       iris %>% left_join(table, by = c("Species" = joincol))
}

你可以称之为:

foobarjoin(table = foobar, joincol = "fooname")

#    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species value
#1            5.1         3.5          1.4         0.2     setosa    20
#2            4.9         3.0          1.4         0.2     setosa    20
#3            4.7         3.2          1.3         0.2     setosa    20
#4            4.6         3.1          1.5         0.2     setosa    20
#5            5.0         3.6          1.4         0.2     setosa    20
#6            5.4         3.9          1.7         0.4     setosa    20
#7            4.6         3.4          1.4         0.3     setosa    20
#8            5.0         3.4          1.5         0.2     setosa    20
#...
#...
rslzwgfq

rslzwgfq2#

对我来说最奇怪的事情是... CmdLvl在我的全局环境中是一个字符变量。由于某些原因,我无法让它工作:

Output <- my_df1 %>% 
    left_join(my_df2 , by = c(CmdLvl = "RSID"))

但这确实有效:

Output <- my_df2 %>% 
    right_join(my_df1 , by = c("RSID" = CmdLvl))

我尝试了很多!!CmdLvl、!!sym(CmdLvl)、Paste 0(CmdLvl)等的变体......没有任何效果。另一种解决方法是复制列并在其上加入,如下所示:

Output <- my_df1 %>% 
    mutate(linker = !! sym(CmdLvl)) %>% #couldn't get CmdLvl to work in leftjoin below, so I replicate the CmdLvl (Unit) column and use that instead
    left_join(my_df2 , by = c("linker"  = "RSID"))

然后,我可以删除'linker'列。我认为right_join是最好的解决方案,直到我弄清楚为什么left_join不允许使用全局环境中的变量作为左侧连接列引用。

相关问题