如何将 tidyselect 样式的列名列表拼接到我的函数调用中
How to splice a tidyselect-style list of column names into a call of my function
我正在尝试编写一个函数来删除分组数据框的重复数据。它断言每个组中的值都相同,然后只保留组的第一行。我正在尝试为它提供类似 pivot_longer()
中类似 tidyselect 的语义,因为我只需要将列名转发到 summary(a = n_distinct(...))
调用中。
举个例子table
test <- tribble(
~G, ~F, ~v1, ~v2,
"A", "a", 1, 2,
"A", "b", 1, 2,
"B", "a", 3, 3,
"B", "b", 3, 3) %>%
group_by(G)
我希望调用 remove_duplicates(test, c(v1, v2))
(使用 tidyselect 助手 c()
到 return
G F v1 v2
A a 1 2
B a 1 2
但我明白了
Error: `arg` must be a symbol
我尝试使用新的 "embrace" 语法来解决这个问题(请参阅下面的函数代码),但失败并显示如上所示的消息。
# Assert that values in each group are identical and keep the first row of each
# group
# tab: A grouped tibble
# vars: <tidy-select> Columns expected to be constant throughout the group
remove_duplicates <- function(tab, vars){
# Assert identical results for identical models and keep only the first per group.
tab %>%
summarise(a = n_distinct({{{vars}}}) == 1, .groups = "drop") %>%
{stopifnot(all(.$a))}
# Remove duplicates
tab <- tab %>%
slice(1) %>%
ungroup()
return(tab)
}
我认为我需要以某种方式指定表达式 vars
的求值上下文必须更改为 tab
当前正在由 [= 求值的子数据框21=]。
所以像
tab %>%
summarise(a = do.call(n_distinct, TIDYSELECT_TO_LIST_OF_VECTORS(vars, context = CURRENT_GROUP))))
但我对技术细节的了解还不足以真正完成这项工作...
如果您首先 enquos
您的 vars
然后对结果使用 curly-curly 运算符,这将按预期工作:
remove_duplicates <- function(tab, vars){
vars <- enquos(vars)
tab %>%
summarise(a = n_distinct({{vars}}) == 1, .groups = "drop") %>%
{stopifnot(all(.$a))}
tab %>% slice(1) %>% ungroup()
}
所以现在
remove_duplicates(test, c(v1, v2))
#> # A tibble: 2 x 4
#> G F v1 v2
#> <chr> <chr> <dbl> <dbl>
#> 1 A a 1 2
#> 2 B a 3 3
我正在尝试编写一个函数来删除分组数据框的重复数据。它断言每个组中的值都相同,然后只保留组的第一行。我正在尝试为它提供类似 pivot_longer()
中类似 tidyselect 的语义,因为我只需要将列名转发到 summary(a = n_distinct(...))
调用中。
举个例子table
test <- tribble(
~G, ~F, ~v1, ~v2,
"A", "a", 1, 2,
"A", "b", 1, 2,
"B", "a", 3, 3,
"B", "b", 3, 3) %>%
group_by(G)
我希望调用 remove_duplicates(test, c(v1, v2))
(使用 tidyselect 助手 c()
到 return
G F v1 v2
A a 1 2
B a 1 2
但我明白了
Error: `arg` must be a symbol
我尝试使用新的 "embrace" 语法来解决这个问题(请参阅下面的函数代码),但失败并显示如上所示的消息。
# Assert that values in each group are identical and keep the first row of each
# group
# tab: A grouped tibble
# vars: <tidy-select> Columns expected to be constant throughout the group
remove_duplicates <- function(tab, vars){
# Assert identical results for identical models and keep only the first per group.
tab %>%
summarise(a = n_distinct({{{vars}}}) == 1, .groups = "drop") %>%
{stopifnot(all(.$a))}
# Remove duplicates
tab <- tab %>%
slice(1) %>%
ungroup()
return(tab)
}
我认为我需要以某种方式指定表达式 vars
的求值上下文必须更改为 tab
当前正在由 [= 求值的子数据框21=]。
所以像
tab %>%
summarise(a = do.call(n_distinct, TIDYSELECT_TO_LIST_OF_VECTORS(vars, context = CURRENT_GROUP))))
但我对技术细节的了解还不足以真正完成这项工作...
如果您首先 enquos
您的 vars
然后对结果使用 curly-curly 运算符,这将按预期工作:
remove_duplicates <- function(tab, vars){
vars <- enquos(vars)
tab %>%
summarise(a = n_distinct({{vars}}) == 1, .groups = "drop") %>%
{stopifnot(all(.$a))}
tab %>% slice(1) %>% ungroup()
}
所以现在
remove_duplicates(test, c(v1, v2))
#> # A tibble: 2 x 4
#> G F v1 v2
#> <chr> <chr> <dbl> <dbl>
#> 1 A a 1 2
#> 2 B a 3 3