如何使用 ggplot 突出显示分面网格中的点?

How to highlight points in a facet grid with ggplot?

我有以下长格式数据:

data <- '"","n","variable","value"
"1",1,"adjr2",0.0365013693015789
"2",2,"adjr2",0.0514307495746085
"3",3,"adjr2",0.0547096973547058
"4",4,"adjr2",0.0552737311430782
"5",5,"adjr2",0.0552933455488706
"6",6,"adjr2",0.0552904097804204
"7",1,"cp",631.119186022639
"8",2,"cp",132.230096988504
"9",3,"cp",23.4429422708563
"10",4,"cp",5.55840294833615
"11",5,"cp",5.9017131979017
"12",6,"cp",7
"13",1,"bic",-1156.56144387716
"14",2,"bic",-1641.2046046544
"15",3,"bic",-1741.38235791823
"16",4,"bic",-1750.90145310605
"17",5,"bic",-1742.19643112204
"18",6,"bic",-1732.73634326858'

df <- read.csv(text=data)

我想为每个变量创建一个点图。目前,我正在使用 ggplot2:

ggplot(df) + geom_point(aes(x = n, y = value, fill = variable)) + 
    facet_grid(variable ~ ., scale="free_y")

结果如下:

我现在想用不同的颜色为每个子图突出显示一个点。我不知道如何将它添加到当前 geom_point,是否可能?

例如,我如何突出显示第一个子图中的最大值和其他两个子图中的最小值?像这样,对于第一个:

我找到了一种方法,可以通过三个单独的图手动完成,然后将它们连接到一个网格中,但该解决方案是 25 行,并且有很多重复代码。有没有办法通过稍微修改上面的代码片段来做到这一点?

(顺便求出最小值和最大值为which.min(df$value[df$variable == 'cp']),等等)

您可以添加一列来标记每个方面的最大值或最小值。下面的代码添加了一列来标记面中的最大值,其中线性回归拟合具有正斜率,当斜率为负时标记最小值。然后将此添加的列映射到颜色美学以设置点颜色。 (您还可以使突出显示的点更大 and/or 通过将新列分别映射到 sizeshape 美学,为它们使用不同的点标记。)

library(dplyr)

df = df %>% 
  group_by(variable) %>%                      # Group by the faceting variable
  mutate(highlight = coef(lm(value ~ n))[2],  # Get slope for each facet
         highlight = ifelse(highlight > 0,    # Mark max or min value, depending on slope
                            ifelse(value==max(value),"Y","N"),
                            ifelse(value==min(value),"Y","N")))

ggplot(df) + 
  geom_point(aes(x = n, y = value, colour=highlight), size=2, show.legend=FALSE) + 
  facet_grid(variable ~ ., scale="free_y") +
  scale_colour_manual(values=c("black","red")) +
  theme_bw()

您可以通过将数据框直接传输到 ggplot 而不是先保存更新的数据框,而无需将新列永久添加到数据框中即可执行此操作:

df %>% 
  group_by(variable) %>% 
  mutate(highlight = coef(lm(value ~ n))[2],
         highlight = ifelse(highlight > 0, 
                            ifelse(value==max(value),"Y","N"),
                            ifelse(value==min(value),"Y","N"))) %>% 
  ggplot() + 
    geom_point(aes(x=n, y=value, colour=highlight), size=2, show.legend=FALSE) + 
    facet_grid(variable ~ ., scale="free_y") +
    scale_colour_manual(values=c("black","red")) +
    theme_bw()