如何在ggplot的interaction()参数中混合使用NSE与标准求值?
解决ggplot中NSE结合interaction()的报错问题
你碰到的问题核心在于:aes_()(旧版标准求值接口)无法自动解析嵌套在interaction()里的符号对象(sym),而interaction()本身需要接收数据框中的实际向量,不是符号类型,所以才会抛出unique() applies only to vectors的错误。下面给你两种可行的解决方案,优先推荐第一种现代NSE语法的方式:
方法1:使用ggplot推荐的NSE语法(aes() + !!解引用)
现在ggplot官方更建议使用aes()配合rlang的!!解引用运算符来处理非标准求值,这种方式更灵活,也能直接解决嵌套函数的NSE问题:
library(dplyr) library(ggplot2) library(rlang) # 你的数据和符号定义 df <- data.frame(time=as.factor(c(10,10,10,10,20,20,20,20,10,10,10,10,20,20,20,20)), cost=as.factor(c(10,20,30,40,10,20,30,40,10,20,30,40,10,20,30,40)), type=c("a","a","a","a","a","a","a","a","b","b","b","b","b","b","b","b"), value=c(40,20,25,10,80,50,30,60,15,70,80,10,50,20,30,40)) a <- "time" b <- "cost" c <- "type" d <- "value" nse_a <- sym(a) nse_b <- sym(b) nse_c <- sym(c) nse_d <- sym(d) # 正确的NSE绘图代码 df %>% ggplot(aes(x=!!nse_b, y=!!nse_d, group=interaction(!!nse_a, !!nse_c), color=!!nse_a, linetype=!!nse_c)) + geom_line(size=1.2)
这里的!!会把你定义的符号对象(比如nse_a)解引用成数据框中对应的列向量,这样interaction()就能拿到正确的输入进行计算,不会再报错。
方法2:兼容旧版aes_()接口的写法
如果你一定要使用aes_(),需要用rlang::expr()先构建出interaction()的完整表达式,再传给aes_():
# 构建group的表达式 group_expr <- expr(interaction(!!nse_a, !!nse_c)) df %>% ggplot(aes_(x=nse_b, y=nse_d, group=group_expr, color=nse_a, linetype=nse_c)) + geom_line(size=1.2)
或者直接把表达式写在aes_()里:
df %>% ggplot(aes_(x=nse_b, y=nse_d, group=expr(interaction(!!nse_a, !!nse_c)), color=nse_a, linetype=nse_c)) + geom_line(size=1.2)
为什么之前的写法会报错?
你之前直接写group=interaction(nse_a,nse_c)时,nse_a和nse_c是rlang的符号对象(不是数据列),interaction()尝试对符号对象执行unique()操作,自然会抛出错误——因为unique()只接受向量类型。而通过!!解引用后,符号会被替换成数据框中的实际列向量,interaction()就能正常工作了。
内容的提问来源于stack exchange,提问作者HSJ
相关产品推荐
相关产品推荐

