使用dplyr编程,传递列名,两个表中的同一列

使用dplyr编程,传递列名,两个表中的同一列,r,function,dplyr,R,Function,Dplyr,我试图在一个表中填入NA值,在另一个表中填入匹配项,类似于在中发生的情况。但是,我更喜欢tidyverse/dplyr解决方案,更重要的是,我需要将此操作概括为一个函数。这里有一个MWE: library(dplyr) df1 <- tibble(x = c("a", "b", "c", "d", "e"), y = c(1, NA, 2, NA, NA)) df2 <- tibble

我试图在一个表中填入NA值,在另一个表中填入匹配项,类似于在中发生的情况。但是,我更喜欢tidyverse/dplyr解决方案,更重要的是,我需要将此操作概括为一个函数。这里有一个MWE:

library(dplyr)
df1 <- tibble(x = c("a", "b", "c", "d", "e"), y = c(1, NA, 2, NA, NA))
df2 <- tibble(x = c("g", "b", "d", "f", "a"), y = c(3, 4, NA, 5, 1))

# Find NA values in df1 which have matches (even NA matches) in df2.
df1 %>% filter(is.na(y) & x %in% df2$x) -> NAs_to_fill_in

# Get the corresponding values from df2.
df2 %>% filter(x %in% NAs_to_fill_in$x) %>% select(y) -> content_for_NAs

# Assign the values from df2 into df1.
df1 %>% filter(is.na(y) & x %in% df2$x) %>% mutate(y = content_for_NAs)

# A tibble: 2 x 2
  x       y$y
  <chr> <dbl>
1 b         4
2 d        NA
但这就是错误所在

Error: Problem with `filter()` input `..1`.
x no applicable method for 'select_' applied to an object of class "logical"
ℹ Input `..1` is `is.na(y) & x %in% df2 %>% select(x)`.
我不完全理解这个错误,因为我没有明确地使用
select
,但是,考虑到以这种方式从两个表传递变量
x
时固有的潜在模糊性,我也不会对此感到惊讶

我读过这本书,但我要么还不够理解,要么我在别的地方错过了一些东西

所需函数将执行以下操作:

fill_in_the_blank <- function(df_with_NAs, df_with_values, column_they_match_on,
                              column_with_values_of_interest){ GOOD CODE HERE }
在空白处填充这里有一种“tidyverse”风格的方法

fill_in_the_blank <- function(df1, df2, common, update) {
  x <- ensym(common)
  y <- ensym(update)
  yvars <- syms(paste0(rlang::as_string(y), c(".x", ".y")))
  df1 %>% 
    left_join(df2 %>% select(!!x, !!y), by=rlang::as_string(x))  %>% 
    mutate("{y}" := coalesce(!!!yvars),
           !!yvars[[1]] := NULL, !!yvars[[2]] := NULL)
}
fill_in_the_blank(df1, df2, x, y)

填空谢谢,这是一个很大的帮助。作为后续行动,什么才能使
common
成为多个列名的向量来匹配?(我保证我会详细了解它的工作原理!就在我觉得自己在R/Tidyverse中很舒服的时候,我突然遇到了
:=
!!
,和
!!!
,这些对我来说都是全新的。)
fill_in_the_blank(df1, df2, x, y)

# A tibble: 5 x 2
  x         y
  <chr> <dbl>
1 a         1
2 b         4
3 c         2
4 d        NA
5 e        NA
fill_in_the_blank <- function(df1, df2, common, update) {
  x <- ensym(common)
  y <- ensym(update)
  yvars <- syms(paste0(rlang::as_string(y), c(".x", ".y")))
  df1 %>% 
    left_join(df2 %>% select(!!x, !!y), by=rlang::as_string(x))  %>% 
    mutate("{y}" := coalesce(!!!yvars),
           !!yvars[[1]] := NULL, !!yvars[[2]] := NULL)
}
fill_in_the_blank(df1, df2, x, y)