I want to write a function which joins two tibbles, with the 2nd tibble's joined column specified in the function's args.
I have
df1 <- tibble(NUMBER = c(1,4))
df2 <- tibble(ORDER = 1:5,
DISORDER = 5:1,
WORD = c("The", "quick", "brown", "fox", "jumped"))
I want
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"))
I've tried several variations on
chozer <- function(df1, df2, ColName){
aCol = enquo(ColName)
inner_join(df1, df2, by = c(NUMBER = aCol))
}
# but they all gave errors.
I looked thru Hadley Wickham's Advanced R, but found no examples of an NSE (nonstand evaluation) being used in the by clause of a join.
Do you know how?
CodePudding user response:
You could use 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
CodePudding user response:
Using rlang::ensym and rlang::as_string you could do:
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
See https://adv-r.hadley.nz/quasiquotation.html#quasi-motivation
CodePudding user response:
An option is also to rename and join by common column
library(dplyr)
chozer <- function(df1, df2, ColName){
df2 %>%
rename(NUMBER := {{ColName}}) %>%
inner_join(df1)
}
-testing
> 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
