如何在tidyr的unite函数中用rlang引用变量实现分组嵌套?
我来帮你搞定这个R里用rlang引用变量的问题!
初始场景与目标
你有下面的初始数据和变量,想要用var代替手动输入的"AB"来完成数据处理,但之前的尝试没得到预期结果:
初始数据和变量:
df <- tibble::tribble( ~A, ~B, ~C, "a", "b", 2L, "a", "b", 4L, "c", "d", 3L, "c", "d", 5L ) var <- "AB"
你期望实现的最终处理效果对应的代码是:
df1 <- df %>% unite("AB", c("A", "B")) %>% group_by(AB) %>% nest()
但你尝试的这段代码没达到预期:
df1 <- df %>% unite(var, c("A", "B")) %>% group_by(!!var) %>% nest()
问题根源
核心问题出在两个地方:
unite的第一个参数需要的是新列的名称,直接传var的话,它会把新列命名为"var"而非你想要的"AB";group_by里的!!var虽然方向正确,但直接传递字符串无法被识别为列名,需要先转换成R的符号对象。
解决方案
这里有两种简洁的方法,利用rlang的整洁评估实现你的需求:
方法1:用sym()+!!转换并解引用
先把字符串变量转换成R的符号对象,再用!!进行解引用,让unite和group_by都能正确识别目标列名:
library(dplyr) library(tidyr) library(rlang) df <- tibble::tribble( ~A, ~B, ~C, "a", "b", 2L, "a", "b", 4L, "c", "d", 3L, "c", "d", 5L ) var <- "AB" df1 <- df %>% unite(!!sym(var), c("A", "B")) %>% # 将var转成符号后解引用 group_by(!!sym(var)) %>% nest()
方法2:用{{}}(整洁评估的简洁语法)
{{}}是整洁评估里的“大括号”语法,能直接帮你处理变量的引用,不管是函数参数还是全局变量都能适用:
df1 <- df %>% unite({{var}}, c("A", "B")) %>% group_by({{var}}) %>% nest()
验证结果
运行上面任意一种代码后,你都会得到和预期完全一致的结果:
> df1 # A tibble: 2 × 2 # Groups: AB [2] AB data <chr> <list> 1 a,b <tibble [2 × 1]> 2 c,d <tibble [2 × 1]>
内容的提问来源于stack exchange,提问作者Geet
相关产品推荐
相关产品推荐

