R 如何防止 ggplot geom_text() 在命名绘图对象上使用新的数据库数据

R how to prevent ggplot geom_text() from using new database data on a named plot object

我正在尝试使用具有独特珊瑚物种数据库的相同代码制作一系列图。

数据库

data_1 <- structure(list(Site_long = structure(c(1L, 1L, 2L, 2L), .Label = c("Hanauma Bay", 
"Waikiki"), class = "factor"), Shelter = structure(c(1L, 2L, 
1L, 2L), .Label = c("Low", "High"), class = c("ordered", "factor"
)), mean = c(1.19986885018767, 2.15593884020962, 0.369605100791602, 
0.31005865611133), sd = c(2.5618758944073, 3.67786619671933, 
1.0285671157698, 0.674643037178562), lower = c(0.631321215232725, 
1.33972360808602, 0.141339007832154, 0.160337623931733), upper = c(1.76841648514261, 
2.97215407233321, 0.59787119375105, 0.459779688290928), sample_size = c(78L, 
78L, 78L, 78L)), row.names = c(NA, -4L), groups = structure(list(
    Site_long = structure(1:2, .Label = c("Hanauma Bay", "Waikiki"
    ), class = "factor"), .rows = structure(list(1:2, 3:4), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = 1:2, class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

data_2 <- structure(list(Site_long = structure(c(2L, 2L, 1L, 1L), .Label = c("Hanauma Bay", 
"Waikiki"), class = "factor"), Shelter = structure(c(1L, 2L, 
1L, 2L), .Label = c("Low", "High"), class = c("ordered", "factor"
)), mean = c(0.695203162997812, 0.838720069947102, 0.76957780057238, 
0.771070502382599), sd = c(1.17117437618039, 1.02766824928792, 
1.43499288333539, 1.28634022958585), lower = c(0.435288768568787, 
0.610653459098997, 0.451115141323908, 0.485597776371556), upper = c(0.955117557426838, 
1.06678668079521, 1.08804045982085, 1.05654322839364), sample_size = c(78L, 
78L, 78L, 78L)), row.names = c(NA, -4L), groups = structure(list(
    Site_long = structure(1:2, .Label = c("Hanauma Bay", "Waikiki"
    ), class = "factor"), .rows = structure(list(3:4, 1:2), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = 1:2, class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

当我 运行 我在第一个物种数据库 (data_1) 上的代码时,条形图和相关的错误条注释呈现正确。请注意,我还创建了一个新变量“data”,它将与稍后用于物种 2 的对象相同。为了保留此图以便稍后将多个图组合在一起,我将该图命名为“species_1_plot " 将其保存到全局环境中。

物种 1 地块代码

data <- data_1

mult_compare_recruitment <- c("A", "A", "A", "A")

data <- data[c(3, 4, 1, 2),]
data$Shelter <- factor(data$Shelter, levels = c("Low", "High"))
# reorder summary dataframe for plotting 

position <- c("Waikiki", "Hanauma Bay")
# ggplot2 barplot position with Waikiki (Low-High Shelter) and Hanauma Bay 

recruitment_plot_3 <- ggplot(data = data, aes(fill=Shelter, y=mean, x=Site_long)) + 
  geom_bar(position = "dodge", stat="identity", width = .8) +
  scale_x_discrete(limits = position) +
  geom_errorbar(aes(ymin = lower, ymax = upper), position = position_dodge(.8), width = .1) +
  geom_text(aes(label = mult_compare_recruitment, y = data$upper), vjust = -.5, position = position_dodge(width = 0.8), size = 4) +
  scale_fill_grey(name = "Shelter", start = .8, end = .2) +
  labs(x = "Site", y = expression(paste("Coral recruitment per m"^"2"))) + 
  theme_classic(base_size = 14.5) +
  theme(text = element_text(size = 18), axis.title.x = element_blank(),
        legend.position = "none", axis.text.y = element_text(angle = 90))

species_1_plot <- recruitment_plot_3

species_1_plot

为了创建我的下一个地块,我 运行 在不同物种数据库 (data_2) 上使用相同的代码,同时再次将新数据库分配给对象“数据”。再一次,我将新的情节“species_2_plot”保存到全局环境中。

物种 2 图的代码

data <- data_2

mult_compare_recruitment <- c("A", "A", "B", "B")

data <- data[c(3, 4, 1, 2),]
data$Shelter <- factor(data$Shelter, levels = c("Low", "High"))
# reorder summary dataframe for plotting 

position <- c("Waikiki", "Hanauma Bay")
# ggplot2 barplot position with Waikiki (Low-High Shelter) and Hanauma Bay 

recruitment_plot_3 <- ggplot(data = data, aes(fill=Shelter, y=mean, x=Site_long)) + 
  geom_bar(position = "dodge", stat="identity", width = .8) +
  scale_x_discrete(limits = position) +
  geom_errorbar(aes(ymin = lower, ymax = upper), position = position_dodge(.8), width = .1) +
  geom_text(aes(label = mult_compare_recruitment, y = data$upper), vjust = -.5, position = position_dodge(width = 0.8), size = 4) +
  scale_fill_grey(name = "Shelter", start = .8, end = .2) +
  labs(x = "Site", y = expression(paste("Coral recruitment per m"^"2"))) + 
  theme_classic(base_size = 14.5) +
  theme(text = element_text(size = 18), axis.title.x = element_blank(),
        legend.position = "none", axis.text.y = element_text(angle = 90))

species_2_plot <- recruitment_plot_3

species_2_plot

问题是,当我再次绘制第一个物种图(species_1_plot)时,数据是正确的(条),但文本注释的高度和它们的字母值不正确。它们实际上是 species_2_plot.

中的值
species_1_plot

我知道这会是个问题,所以我用唯一的名称将每个地块保存到全局环境中。但是尽管如此,geom_text() 似乎正在使用第二个图(全局环境中的代码)中的数据,而不是尽管图中的实际数据(条)是正确的(来自 species_plot_1 ).我的理解是,当您将绘图命名为对象(species_1_plot 和 species_2_plot)时,这类似于保存绘图,因此除非指定,否则防止对绘图和注释进行任何更改。如果不特别命名数据库(data_1 和 data_2),有什么方法可以防止这种情况发生?感谢所有输入。提前致谢!

我建议您使用具有函数的方法。使用 data 两次的事实可能改变了环境,结果情节发生了变化。我创建了一个带有数据、职位和招聘参数的函数,并显示了输出。您必须按照在代码中定义变量的方式来填充它们。函数在内部环境中工作,因此可能不存在关于如何处理数据的问题。这是我使用您共享的数据的代码:

library(ggplot2)
#Function
myplotfunc <- function(x,y,z)
{
    data <- x
    
    mult_compare_recruitment <- y
    
    data <- data[c(3, 4, 1, 2),]
    data$Shelter <- factor(data$Shelter, levels = c("Low", "High"))
    # reorder summary dataframe for plotting 
    
    position <- z
    # ggplot2 barplot position with Waikiki (Low-High Shelter) and Hanauma Bay 
    
    plot <- ggplot(data = data, aes(fill=Shelter, y=mean, x=Site_long)) + 
        geom_bar(position = "dodge", stat="identity", width = .8) +
        scale_x_discrete(limits = position) +
        geom_errorbar(aes(ymin = lower, ymax = upper), position = position_dodge(.8), width = .1) +
        geom_text(aes(label = mult_compare_recruitment, y = data$upper), vjust = -.5, position = position_dodge(width = 0.8), size = 4) +
        scale_fill_grey(name = "Shelter", start = .8, end = .2) +
        labs(x = "Site", y = expression(paste("Coral recruitment per m"^"2"))) + 
        theme_classic(base_size = 14.5) +
        theme(text = element_text(size = 18), axis.title.x = element_blank(),
              legend.position = "none", axis.text.y = element_text(angle = 90))
    return(plot)
}
#Code
o1 <- myplotfunc(x=data_1,y=c("A", "A", "A", "A"),z=c("Waikiki", "Hanauma Bay"))
o2 <- myplotfunc(x=data_2,y=c("A", "A", "B", "B"),z=c("Waikiki", "Hanauma Bay"))

输出: