如何在分面和使用可变列名时保持颜色正确?

How to keep colours correct when facetting and using variable column names?

我正在尝试制作这样的多面图:

example_data <- data.frame(x = rnorm(100, mean = 0, sd = 1), 
                           y = rnorm(100, mean = 0, sd = 1),
                           facet=sample(c(0,1), replace=TRUE, size=100))

ggplot(example_data, aes(x=x, y=y, colour=sign(x)!=sign(y)))+
  geom_point()+
  geom_hline(yintercept=0)+
  geom_vline(xintercept=0)+
  facet_wrap(~facet)

但是,我正在为列名可变的多个图执行此操作。对于绘制 x 和 y,这可以使用 aes_string,并且在没有刻面的情况下,这也适用于颜色:

ggplot(example_data, aes_string(x='x', y='y', colour=sign(example_data[['x']])!=sign(example_data[['y']])))+
  geom_point()+
  geom_hline(yintercept=0)+
  geom_vline(xintercept=0)+
  guides(col=F)

但是当我刻面时,颜色不再正确:

ggplot(example_data, aes_string(x='x', y='y', colour=sign(example_data[['x']])!=sign(example_data[['y']])))+
  geom_point()+
  geom_hline(yintercept=0)+
  geom_vline(xintercept=0)+
  guides(col=F)+
  facet_wrap(~facet)

我猜这是因为点的顺序取决于它们在哪个方面。我可以通过获取每个方面的颜色来解决这个问题:

 col_facet_0 <- sign(example_data[example_data$facet==0,][['x']])!=sign(example_data[example_data$facet==0,][['y']])
 col_facet_1 <- sign(example_data[example_data$facet==1,][['x']])!=sign(example_data[example_data$facet==1,][['y']])
 col <- c(col_facet_0, col_facet_1)

ggplot(example_data, aes_string(x='x', y='y', colour=col))+
  geom_point()+
  geom_hline(yintercept=0)+
  geom_vline(xintercept=0)+
  guides(col=F)+
  facet_wrap(~facet)

问题是,我需要事先知道哪些面颜色需要位于颜色向量的开头,哪些位于最后。例如,在上面的代码中,如果我使用 col <- c(col_facet_1, col_facet_0) 代替,颜色就会出错。

我的问题是,有没有一种方法可以在 ggplot 函数中执行此操作,这样我就不需要知道哪个方面必须是第一个?

您可以将表达式设为字符串,如下所示:

ggplot(example_data, aes_string(x='x', y='y', colour='sign(x) != sign(y)'))+
  geom_point()+
  geom_hline(yintercept=0)+
  geom_vline(xintercept=0)+
  guides(col=F)

如果您需要灵活的列名,可以这样做,例如:

x_col <- 'x'
y_col <- 'y'

ggplot(
  example_data, 
  aes_string(x_col, y_col, colour = sprintf('sign(%s) != sign(%s)', x_col, y_col))
) + ...