R语言如何复制ggpattern包环境对象并去除第三方库依赖
问题说明
问题概述
我需要从R包ggpattern中提取所需的相关代码,但遇到库中两个环境对象无法在包外独立复制的问题。
背景说明
我所在组织的R Studio Server Pro因ggpattern依赖gridpattern、magik包(尤其是magik与服务器配置不兼容),不允许安装完整ggpattern包,因此我仅需复制ggpattern中绘制条纹柱状图的必要代码。我已获得包维护者的操作许可,对方也确认ggpattern是纯R包,我所需的功能无需使用magik。
我需要运行的核心ggpattern代码用于生成带条纹柱子的柱状图,代码如下:
ggplot(wr, aes(x = A, y = P, fill = interaction(C, W), pattern = W.P)) + geom_bar_pattern(stat = "identity", position = "dodge", color = "black", pattern_angle = 45, pattern_density = 0.5, pattern_key_scale_factor = 0.41, pattern_fill = "white", pattern_color = "white") + scale_pattern_manual(values = c("GP" = "none", "WII" = "stripe", "SLM" = "none"), labels = c("GP","WII","SLM"))
我需要用到ggpattern中的geom_bar_pattern()和scale_pattern_manual()两个函数。
已尝试操作
我已尽可能溯源ggpattern及其依赖中geom_bar_pattern()、scale_pattern_manual()的底层实现,将这些函数整理到独立脚本中。目前剩余问题是这些函数还依赖GeomBarPattern、GeomRectPattern两个环境对象,我无法复制这两个对象并使其脱离ggpattern、gridpattern、magik等依赖包独立运行。
我曾在可正常使用ggpattern的本地设备上将两个环境对象保存为.RData文件,操作代码如下:
GeomBarPattern <- ggpattern::GeomBarPattern save(GeomBarPattern, file = "./Prototype/GeomBarPattern.RData") GeomRectPattern <- ggpattern::GeomRectPattern save(GeomRectPattern, file = "./Prototype/GeomRectPattern.RData")
将上述文件上传到R Studio Server Pro加载时,出现如下报错:
> load("GeomBarPattern.RData") Warning: namespace ‘ggpattern’ is not available and has been replaced by .GlobalEnv when processing object ‘GeomBarPattern’ > load("GeomRectPattern.RData") Warning: namespace ‘ggpattern’ is not available and has been replaced by .GlobalEnv when processing object ‘GeomRectPattern’
解决方案
- 放弃使用.RData序列化对象,改用纯代码导出ggproto定义
.RData存储的对象会绑定原包的命名空间,加载时缺少原包就会触发警告、无法正常运行。你可以在本地装有ggpattern的环境中,用dput()函数将两个ggproto对象直接输出为可复现的纯R代码,完全脱离原包绑定:
dput(ggpattern::GeomRectPattern, file = "GeomRectPattern.R") dput(ggpattern::GeomBarPattern, file = "GeomBarPattern.R")
- 剥离无关依赖
你仅需none和stripe两种图案,不需要用到magik相关功能,打开上述导出的两个R文件,删除所有调用magik、gridpattern非必要函数的逻辑,仅保留条纹绘制的核心代码即可。如果嫌修改麻烦,可以直接用下面的自定义简化版实现,仅依赖ggplot2和grid两个基础包,无需额外安装其他依赖:
library(ggplot2) library(grid) # 自定义仅支持条纹和无图案的Rect Geom GeomRectPatternStripe <- ggproto( "GeomRectPatternStripe", GeomRect, draw_panel = function(self, data, panel_params, coord, pattern = "none", pattern_angle = 45, pattern_density = 0.5, pattern_fill = "white", pattern_color = "white", pattern_key_scale_factor = 0.41) { coords <- coord$transform(data, panel_params) # 遍历每个矩形绘制 for (i in seq(nrow(coords))) { row <- coords[i, ] # 绘制底色 grid.rect( x = row$xmin, y = row$ymax, width = row$xmax - row$xmin, height = row$ymax - row$ymin, just = c("left", "top"), gp = gpar( col = row$colour, fill = row$fill, lwd = row$linewidth * .pt, lty = row$linetype ) ) # 绘制条纹 if (row$pattern == "stripe") { line_spacing <- unit(1/(pattern_density*10), "cm") grid.pattern( pattern = "stripe", x = row$xmin, y = row$ymax, width = row$xmax - row$xmin, height = row$ymax - row$ymin, just = c("left", "top"), angle = pattern_angle, spacing = line_spacing, gp = gpar(col = pattern_color, fill = pattern_fill) ) } } } ) # 自定义geom_bar_pattern geom_bar_pattern <- function(mapping = NULL, data = NULL, stat = "identity", position = "dodge", ..., width = NULL, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { layer( data = data, mapping = mapping, stat = stat, geom = GeomRectPatternStripe, position = position, show.legend = show.legend, inherit.aes = inherit.aes, params = list(width = width, na.rm = na.rm, ...) ) } # 自定义scale_pattern_manual scale_pattern_manual <- function(values, labels, ...) { scale_discrete_manual(aesthetics = "pattern", values = values, labels = labels, ...) }
- 运行核心代码
将上述自定义代码放在你原有绘图脚本的最前面,不需要加载ggpattern、gridpattern、magik,即可正常运行你原本的条纹柱状图绘制代码。
内容的提问来源于stack exchange,提问作者DataCoder
相关产品推荐
相关产品推荐

