dplyr管道中ggplot的sec_axis转换失效问题求助
解决dplyr管道中ggplot sec_axis引用数据列的冲突问题
报错原因
核心问题是sec_axis的trans公式里的.,和管道中指代数据集的.完全不是一回事:
- 管道里的
.代表当前传递的数据集(数据框); - 但sec_axis的trans参数是一个公式,公式里的
.默认指代主轴的数值(原子向量)。
所以你用.$nPatients时,相当于给一个原子向量用$操作符,必然触发$ operator is invalid for atomic vectors报错。
管道内的解决方案
以下几种方法都不需要把变量提到管道外,直接在管道内解决:
方法1:用.x指代主轴数值 + with()绑定数据集
把公式里的主轴数值用.x表示,同时用with(., ...)将管道传递的数据集作为环境,直接引用列名即可:
your_data %>% ggplot(aes(x = category, y = count)) + geom_col() + scale_y_continuous( sec.axis = sec_axis( trans = with(., ~ .x / max(nPatients) * 100), # .x=主轴数值,with里的.=管道数据集 name = "占总患者数百分比" ) )
方法2:用cur_data()获取当前数据集
dplyr的cur_data()函数可以在ggplot上下文里直接拿到管道传递的数据集,结合.x指代主轴数值,避免冲突:
your_data %>% ggplot(aes(x = category, y = count)) + geom_col() + scale_y_continuous( sec.axis = sec_axis( trans = ~ .x / max(cur_data()$nPatients) * 100, name = "占总患者数百分比" ) )
方法3:提前计算统计量到新列
如果需要重复使用nPatients的统计值,可以先在管道里计算并存为新列,之后在sec_axis里引用:
your_data %>% mutate(total_patients = max(nPatients)) %>% ggplot(aes(x = category, y = count)) + geom_col() + scale_y_continuous( sec.axis = sec_axis( trans = ~ .x / unique(cur_data()$total_patients) * 100, name = "占总患者数百分比" ) )
内容的提问来源于stack exchange,提问作者PhDavey
相关产品推荐
相关产品推荐

