根据长数据上 id 变量的值(与行号无关)为 ggplot 中的特定标签着色

Colouring specific label in ggplot depending on the value of the id variable on a long data (irrespectively of the row number)

假设我有一个长数据集,我想在 x 轴上为特定标签着色。在下面的示例中,我想为 Valiant.

的标签着色
# Packs
require(ggplot2)
require(reshape2)

# Data and trans
data(mtcars)
mtcars$model <- rownames(mtcars)
mtcars <- melt(mtcars, id.vars = "model")

# Some chart
ggplot(data = subset(x = mtcars, subset = mtcars$variable == "cyl"), 
       aes(x = model, y = value)) +
    geom_bar(stat = "identity") +
    theme(axis.text.x = element_text(angle = 90, 
                                     colour =
                                         ifelse(mtcars$model == "Valiant",
                                                "red","black")))

代码生成了下面错误的图表,因为错误的标签被涂上了颜色。

原因很简单,因为 ifelse 创建的内容与轴上的顺序不匹配。我可以通过强制 ggplot 为特定行着色来修复代码。下面的代码为图表中使用的特定 data.frame 中的正确标签着色,具有 Valiant 值的行是 31.

# Fixed chart
ggplot(data = subset(x = mtcars, subset = mtcars$variable == "cyl"), 
       aes(x = model, y = value)) +
    geom_bar(stat = "identity") +
    theme(axis.text.x = element_text(angle = 90, 
                                     colour =
                                         ifelse(as.numeric(rownames(mtcars)) == 31,
                                                "red","black")))

显然这个解决方案是极其不切实际的。在实际数据上,我有大量的多列观察(地理、性别、指标、价值等)。随后通过子集过滤该数据,并将不同的选项传递给 aes 设置。试图找出应该着色的行是一场噩梦。我正在寻找一种解决方案,使我能够:

第一个不匹配的原因是 mtcars$model 比您正在绘制的子集长得多,因此颜色向量 ifelse(mtcars$model == "Valiant","red","black") 的长度为 352 但您正在绘制的子集仅为长度 32。您的第二个示例存在同样的问题,但在这种情况下 colour 的额外元素(无论如何都是 "black")被删除,因此您不会注意到。

不幸的是,theme(...) 似乎没有使用可用的数据列名称进行评估(即不能直接在 theme(...) 调用中执行 colour=ifelse(model == "Valiant", "red", "black")

一种替代方法是使 model 成为一个因素并在 levels(..) == "Valiant" 上进行过滤。如果你有一个长数据框,你的 id 变量很可能是一个因素(或者它是一个因素是有意义的)。

mtcars$model = factor(mtcars$model)
ggplot(data=subset(mtcars, variable == 'cyl'), aes(x=model, y=value)) +
    geom_bar(stat="identity") +
    theme(axis.text.x=element_text(angle=90,
              colour=ifelse(levels(mtcars$model) == 'Valiant', 'red', 'black')))

(您的问题源于将 subset() 作为您的数据输入 ggplot,然后无法在 theme 调用中返回到该特定子集。我不知道是否存在这是一种棘手的方法。