问题描述
我正在尝试编写一个对已分组的数据帧进行重复数据删除的函数。它断言每个组中的值都相同,然后仅保留该组的第一行。我试图赋予它类似pivot_longer()
的tidyselect语义,因为我只需要将列名转发到summary(a = n_distinct(...))
调用中即可。
以表格为例
test <- tribble(
~G,~F,~v1,~v2,"A","a",1,2,"b","B",3,3) %>%
group_by(G)
我希望电话remove_duplicates(test,c(v1,v2))
(使用tidyselect助手c()
会返回
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
当前正在评估的substitute
的子数据帧。 }。
所以像
tab %>%
summarise(a = do.call(n_distinct,TIDYSELECT_TO_LIST_OF_VECTORS(vars,context = CURRENT_GROUP))))
但是我对技术细节了解不足,无法真正完成这项工作...
解决方法
如果您首先enquos
vars
,然后对结果使用curl-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