Inner_join 在 NSE 上
Inner_join on NSE
我想编写一个连接两个小标题的函数,第二个小标题的连接列在函数的参数中指定。
我有
df1 <- tibble(NUMBER = c(1,4))
df2 <- tibble(ORDER = 1:5,
DISORDER = 5:1,
WORD = c("The", "quick", "brown", "fox", "jumped"))
我要
chozer(df1, df2, ORDER)
# to yield
tibble(NUMBER = c(1,4),
DISORDER = c(5,2),
WORD = c("The", "fox"))
# and
chozer(df1, df2, DISORDER)
# to yield
tibble(NUMBER = c(5,2),
DISORDER = c(1,4),
WORD = c("jumped", "quick"))
我已经尝试了几种变体
chozer <- function(df1, df2, ColName){
aCol = enquo(ColName)
inner_join(df1, df2, by = c(NUMBER = aCol))
}
# but they all gave errors.
我查看了 Hadley Wickham 的 Advanced R,但没有发现在联接的 by
子句中使用 NSE(非标准求值)的示例。
你知道怎么做吗?
你可以使用 deparse(substitute(ColName))
:
chozer <- function(df1, df2, ColName){
inner_join(df1, df2, by = c(NUMBER = deparse(substitute(ColName))))
}
chozer(df1, df2, DISORDER)
# A tibble: 2 x 3
NUMBER ORDER WORD
<dbl> <int> <chr>
1 1 5 jumped
2 4 2 quick
chozer(df1, df2, ORDER)
# A tibble: 2 x 3
NUMBER DISORDER WORD
<dbl> <int> <chr>
1 1 5 The
2 4 2 fox
使用 rlang::ensym
和 rlang::as_string
你可以:
library(dplyr)
df1 <- tibble(NUMBER = c(1,4))
df2 <- tibble(ORDER = 1:5,
DISORDER = 5:1,
WORD = c("The", "quick", "brown", "fox", "jumped"))
chozer <- function(df1, df2, ColName){
aCol = ensym(ColName)
inner_join(df1, df2, by = c(NUMBER = rlang::as_string(aCol)))
}
chozer(df1, df2, ORDER)
#> # A tibble: 2 × 3
#> NUMBER DISORDER WORD
#> <dbl> <int> <chr>
#> 1 1 5 The
#> 2 4 2 fox
chozer(df1, df2, DISORDER)
#> # A tibble: 2 × 3
#> NUMBER ORDER WORD
#> <dbl> <int> <chr>
#> 1 1 5 jumped
#> 2 4 2 quick
见https://adv-r.hadley.nz/quasiquotation.html#quasi-motivation
一个选项也是 rename
并按公共列加入
library(dplyr)
chozer <- function(df1, df2, ColName){
df2 %>%
rename(NUMBER := {{ColName}}) %>%
inner_join(df1)
}
-测试
> chozer(df1, df2, ORDER)
Joining, by = "NUMBER"
# A tibble: 2 × 3
NUMBER DISORDER WORD
<dbl> <int> <chr>
1 1 5 The
2 4 2 fox
> chozer(df1, df2, DISORDER)
Joining, by = "NUMBER"
# A tibble: 2 × 3
ORDER NUMBER WORD
<int> <dbl> <chr>
1 2 4 quick
2 5 1 jumped
我想编写一个连接两个小标题的函数,第二个小标题的连接列在函数的参数中指定。
我有
df1 <- tibble(NUMBER = c(1,4))
df2 <- tibble(ORDER = 1:5,
DISORDER = 5:1,
WORD = c("The", "quick", "brown", "fox", "jumped"))
我要
chozer(df1, df2, ORDER)
# to yield
tibble(NUMBER = c(1,4),
DISORDER = c(5,2),
WORD = c("The", "fox"))
# and
chozer(df1, df2, DISORDER)
# to yield
tibble(NUMBER = c(5,2),
DISORDER = c(1,4),
WORD = c("jumped", "quick"))
我已经尝试了几种变体
chozer <- function(df1, df2, ColName){
aCol = enquo(ColName)
inner_join(df1, df2, by = c(NUMBER = aCol))
}
# but they all gave errors.
我查看了 Hadley Wickham 的 Advanced R,但没有发现在联接的 by
子句中使用 NSE(非标准求值)的示例。
你知道怎么做吗?
你可以使用 deparse(substitute(ColName))
:
chozer <- function(df1, df2, ColName){
inner_join(df1, df2, by = c(NUMBER = deparse(substitute(ColName))))
}
chozer(df1, df2, DISORDER)
# A tibble: 2 x 3
NUMBER ORDER WORD
<dbl> <int> <chr>
1 1 5 jumped
2 4 2 quick
chozer(df1, df2, ORDER)
# A tibble: 2 x 3
NUMBER DISORDER WORD
<dbl> <int> <chr>
1 1 5 The
2 4 2 fox
使用 rlang::ensym
和 rlang::as_string
你可以:
library(dplyr)
df1 <- tibble(NUMBER = c(1,4))
df2 <- tibble(ORDER = 1:5,
DISORDER = 5:1,
WORD = c("The", "quick", "brown", "fox", "jumped"))
chozer <- function(df1, df2, ColName){
aCol = ensym(ColName)
inner_join(df1, df2, by = c(NUMBER = rlang::as_string(aCol)))
}
chozer(df1, df2, ORDER)
#> # A tibble: 2 × 3
#> NUMBER DISORDER WORD
#> <dbl> <int> <chr>
#> 1 1 5 The
#> 2 4 2 fox
chozer(df1, df2, DISORDER)
#> # A tibble: 2 × 3
#> NUMBER ORDER WORD
#> <dbl> <int> <chr>
#> 1 1 5 jumped
#> 2 4 2 quick
见https://adv-r.hadley.nz/quasiquotation.html#quasi-motivation
一个选项也是 rename
并按公共列加入
library(dplyr)
chozer <- function(df1, df2, ColName){
df2 %>%
rename(NUMBER := {{ColName}}) %>%
inner_join(df1)
}
-测试
> chozer(df1, df2, ORDER)
Joining, by = "NUMBER"
# A tibble: 2 × 3
NUMBER DISORDER WORD
<dbl> <int> <chr>
1 1 5 The
2 4 2 fox
> chozer(df1, df2, DISORDER)
Joining, by = "NUMBER"
# A tibble: 2 × 3
ORDER NUMBER WORD
<int> <dbl> <chr>
1 2 4 quick
2 5 1 jumped