You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决ggplot+dplyr管道中数据集引用错误导致的fill参数报错

问题概述

用户拥有如下crude_data数据集:

crude_data <- structure(list(date = structure(c(19570, 19601, 19631, 19662, 
19692, 19723, 19754, 19783, 19814, 19844, 19875, 19905, 19936, 
19967, 19997, 20028, 20058, 20089, 20120, 20148, 20179, 20209, 
20240, 20270, 20301, 20332, 20362, 20393, 20423, 19570, 19601, 
19631, 19662, 19692, 19723, 19754, 19783, 19814, 19844, 19875, 
19905, 19936, 19967, 19997, 20028, 20058, 20089, 20120, 20148, 
20179, 20209, 20240, 20270, 20301, 20332, 20362, 20393, 20423
), class = "Date"), Key = c("Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Net Inventory Withdrawls (million b/d)", "Net Inventory Withdrawls (million b/d)", 
"Brent Price (USD)", "Brent Price (USD)", "Brent Price (USD)", 
"Brent Price (USD)", "Brent Price (USD)", "Brent Price (USD)", 
"Brent Price (USD)", "Brent Price (USD)", "Brent Price (USD)", 
"Brent Price (USD)", "Brent Price (USD)", "Brent Price (USD)", 
"Brent Price (USD)", "Brent Price (USD)", "Brent Price (USD)", 
"Brent Price (USD)", "Brent Price (USD)", "Brent Price (USD)", 
"Brent Price (USD)", "Brent Price (USD)", "Brent Price (USD)", 
"Brent Price (USD)", "Brent Price (USD)", "Brent Price (USD)", 
"Brent Price (USD)", "Brent Price (USD)", "Brent Price (USD)", 
"Brent Price (USD)", "Brent Price (USD)"), Value = c(1.28, 0.18, 
-0.96, -0.53, -0.01, -0.2, 1.83, -0.57, -0.51, -0.13, 1.46, 0.13, 
0.48, 1.1, -0.4, 0.1, 1.75, -0.69, 2.34, 0.62, -0.75, -0.81, 
0.39, -0.8, -0.58, -0.22, -1.87, -0.86, 0.91, 86.15, 93.72, 90.6, 
82.94, 77.63, 80.12, 83.48, 85.41, 89.94, 81.75, 79, 81, 83, 
86, 86, 87, 87, 88, 88, 88, 86, 86, 86, 85, 85, 85, 83, 83, 82
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-58L))

尝试用dplyr管道结合ggplot2绘图,代码如下:

crude_data %>% {
  ggplot(., aes(date, Value)) + 
    facet_wrap(~Key, nrow=2, scales = 'free_y', strip.position = 'left') +
    annotate("rect", xmin = today() - months(1), xmax = tail(.$date, 1), 
             ymin = -Inf, ymax = Inf, fill = "red", alpha= 0.3) +
    geom_line(data = subset(., date<=today() & Key == 'Brent Price (USD)'), linewidth = 2, col = '#6d1d26', aes(linetype='dashed')) +
    geom_line(data=subset(., date>=today() - months(1) & Key == 'Brent Price (USD)'), linewidth = 2, col = '#6d1d26', aes(linetype='solid')) 
    geom_bar(data = subset(., Key == 'Net Inventory Withdrawls (million b/d)'), 
             fill =  ifelse(. %>% filter(Key == 'Net Inventory Withdrawls (million b/d)') %>% select(Value) > 0, 'red', 'green'),stat='identity')
}

运行后在geom_bar的fill参数判断中报错:

Error in . %>% filter(Key == "Net Inventory Withdrawls (million b/d)") %>%  : 
  comparison (>) is possible only for atomic and list types
错误原因
  1. 类型不匹配:用.%>% filter(...) %>% select(Value)得到的是一个tibble(数据框),不是可以直接和0比较的原子数值向量,因此触发类型错误;
  2. 冗余筛选:已经通过data = subset(., Key == 'Net Inventory Withdrawls (million b/d)')筛选出库存数据子集,无需再全局筛选一次;
  3. 语法遗漏:geom_line和geom_bar之间缺少+号,破坏了ggplot的图层拼接语法。
修正后的代码
library(dplyr)
library(ggplot2)
library(lubridate)

crude_data %>% {
  ggplot(., aes(date, Value)) + 
    facet_wrap(~Key, nrow=2, scales = 'free_y', strip.position = 'left') +
    annotate("rect", xmin = today() - months(1), xmax = tail(.$date, 1), 
             ymin = -Inf, ymax = Inf, fill = "red", alpha= 0.3) +
    geom_line(data = subset(., date<=today() & Key == 'Brent Price (USD)'), linewidth = 2, col = '#6d1d26', aes(linetype='dashed')) +
    geom_line(data=subset(., date>=today() - months(1) & Key == 'Brent Price (USD)'), linewidth = 2, col = '#6d1d26', aes(linetype='solid')) +
    geom_bar(data = subset(., Key == 'Net Inventory Withdrawls (million b/d)'), 
             fill = ifelse(Value > 0, 'red', 'green'), stat='identity')
}

关键修改点

  • 补上geom_line与geom_bar之间的+号,保证图层拼接语法正确;
  • geom_bar的fill参数直接使用ifelse(Value > 0, 'red', 'green'):因为当前图层的数据已经是筛选后的库存数据,Value就是对应的数值向量,可以直接和0比较。

备选方案(若坚持管道方式)

如果一定要用管道提取向量,可通过pull(Value)将数据框转换为原子向量:

geom_bar(data = subset(., Key == 'Net Inventory Withdrawls (million b/d)'), 
         fill = ifelse(subset(., Key == 'Net Inventory Withdrawls (million b/d)') %>% pull(Value) > 0, 'red', 'green'), 
         stat='identity')

内容的提问来源于stack exchange,提问作者Tanga94

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 07:47:05