创建一个同时使用字符串和变量调用列的函数 - 使用 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
我需要一些帮助来理解评估在我正在编写的函数中的工作原理:
该函数将执行两个涉及列“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