创建一个同时使用字符串和变量调用列的函数 - 使用 base R 和 dplyr

Creating a function that calls a column both using a string and as a variable - use of base R and dplyr

我需要一些帮助来理解评估在我正在编写的函数中的工作原理:

该函数将执行两个涉及列“id”的操作,其名称由用户提供,以及其他一些省略的内容:

possible_matches <- function(i, df, id){
  
  k1 <- df$j[df$id == df$id[i]]
  df3 <-  df%>%
    mutate(index = {{id}})
  
  list(df3, k1)
}

如您所见,这将使用两种不同的调用方式 id - 是否有统一这两种方法的简单方法?起初,我尝试在第一部分中写一些东西 df[, 'id'] == df[i, 'id],但这会给出一个错误,指出无法比较大小不等的数据帧。

这是一个例子:

df <- data.frame(V1 = c(1:5, 2:6),
                 j = 1:10)


possible_matches(2, df, V1)

给我:

[[1]]
   V1  j index
1   1  1     1
2   2  2     2
3   3  3     3
4   4  4     4
5   5  5     5
6   2  6     2
7   3  7     3
8   4  8     4
9   5  9     5
10  6 10     6

[[2]]
integer(0)

这显然是错误的,因为至少有一行的 V1 值等于 df$V1[2]

如果 id 是不带引号的列名

possible_matches <- function(i, df, id) {
     
     # // convert the id to string with `as_name` after converting to quosure
     idnew <- rlang::as_name(rlang::enquo(id))
     # // now we use [[ to subset the column and then specify the i index
     k1 <- df$j[df[[idnew]] == df[[idnew]][i]]
      df3 <-  df%>%
         mutate(index = {{id}}) # // curly-curly for quosure + evaluation (!!)

       list(df3, k1)
   }
    

-测试

possible_matches(2, df, V1)
#[[1]]
#   V1  j index
#1   1  1     1
#2   2  2     2
#3   3  3     3
#4   4  4     4
#5   5  5     5
#6   2  6     2
#7   3  7     3
#8   4  8     4
#9   5  9     5
#10  6 10     6

#[[2]]    
#[1] 2 6

如果我们想使用filter

possible_matches <- function(i, df, id) {            
        to_filter <- df%>% 
                      # // select the column
                      select({{id}}) %>% 
                      # // slice the row
                      slice(i) %>%
                      # // pull the column as vector
                      pull(1)
         k1 <- df %>% 
                   # // now we filter with the value from to_filter
                   filter({{id}} == to_filter) %>%
                   pull(j)
            df3 <-  df%>%
                mutate(index = {{id}})
       
              list(df3, k1)
         
         
       
      }
possible_matches(2, df, V1)
#[[1]]
#   V1  j index
#1   1  1     1
#2   2  2     2
#3   3  3     3
#4   4  4     4
#5   5  5     5
#6   2  6     2
#7   3  7     3
#8   4  8     4
#9   5  9     5
#10  6 10     6

#[[2]]
#[1] 2 6