如何根据2个条件在 ggplot 中设置绘图的颜色数值?

huangapple go评论62阅读模式
英文:

How to set the color value in a plot based on 2 conditions ggplot

问题

以下是代码的翻译部分:

我试图制作一个分组的柱状图。我重复使用了一个之前有效的脚本,但在那个脚本中,我不需要根据条件着色。这是我现在尝试并且失败的内容。
我希望根据条件和值是低于还是高于0来着色柱状图。
示例数据:

library(ggplot2)
library(reshape2)
library(Rcpp)

prot_names <- c("Prot_A", "Prot_B", "Prot_C")
Expression_Con_A <- c(-1, 2, 1)
Expression_Con_B <- c(-2, 1.5, 0.5)

df <- data.frame(prot_names, Expression_Con_A, Expression_Con_B)
melt_dat <- melt(df)

我想象中的代码是:

for (i in 1:length(melt_dat$value)) {
  if (melt_dat$value[i] > 0 && melt_dat$variable[i] == "Con_A") {
    melt_dat$color[i] <- "skyblue1"
  } else if (melt_dat$value[i] < 0 && melt_dat$variable[i] == "Con_A") {
    melt_dat$color[i] <- "red1"
  } else if (melt_dat$value[i] > 0 && melt_dat$variable[i] == "Con_B") {
    melt_dat$color[i] <- "skyblue4"
  } else if (melt_dat$value[i] < 0 && melt_dat$variable[i] == "Con_B") {
    melt_dat$color[i] <- "red4"
  }
}

然而,这给了我以下错误:
错误:条件的长度大于1

https://stackoverflow.com/questions/43599859/ggplot2-how-to-color-a-graph-by-multiple-variables
这种方法在某种程度上有效,但它给了我柱子和框架不同的颜色,这不是我想要的。

我还尝试手动设置颜色:

g <- ggplot(melt_dat, aes(x = value, y = prot_names, fill = variable)) +
  geom_bar(stat = 'identity', position = 'dodge') +
  scale_fill_manual(values = c("red1", "skyblue1", "red1", "red4", "skyblue4", "red4"))

但这也不起作用,因为它只根据条件着色(独立于值>0)。

请注意,我已经修正了你的循环和变量名称,以确保代码正确运行。但你可能需要进一步调整以满足你的需求。

英文:

I am trying to make a grouped barchart. I've reused an older script that worked before, however in that script i didn't have to color based on conditions. This is what I am trying now and failing at.
I want the bars to be coloured based on the Condition and if the value is below or above 0
Example data:

library( ggplot2)
library(reshape2)
library(Rcpp)


 prot_names &lt;- c(&quot;Prot_A&quot;, &quot;Prot_B&quot;,&quot;Prot_C&quot;)
Expression_Con_A &lt;- c(-1,2,1)
Expression_Con_B &lt;- c(-2,1.5,0.5)

df &lt;- data.frame(prot_names, Expression_Con_A, Expression_Con_B)
melt_dat &lt;- melt((df))

I'm imagining something like:

for (i in melt_dat$value) {
  if (melt_dat$value[i] &gt; 0 &amp; melt_dat$variable== &quot;ConA&quot;)
  {melt_dat$color&lt;- skyblue1}
  else if (melt_dat$value[i] &lt; 0 &amp; melt_dat$variable== &quot;ConA&quot;)
  {melt_dat$color&lt;- red1}
  else if (melt_dat$value[i] &gt; 0 &amp; melt_dat$variable== &quot;ConB&quot;)
  {melt_dat$color&lt;- skyblue4}
  else if (melt_dat$value[i] &lt; 0 &amp; melt_dat$variable== &quot;ConB&quot;)
  {melt_dat$color&lt;- red4}
}

However this gives me the folowing error:
Error in if (melt_dat$value[i] &gt; 0 &amp; melt_dat$variable == &quot;ConA&quot;) { :
the condition has length > 1

https://stackoverflow.com/questions/43599859/ggplot2-how-to-color-a-graph-by-multiple-variables
This worked in a way but it gave me my bars in a colour and the frame in another which is not what I want

I also tried putting in the colors by hand

g&lt;-ggplot(melt_dat, aes(x=value, y=prot_names, fill=variable))+
            geom_bar(stat=&#39;identity&#39;, position=&#39;dodge&#39;)+
            scale_fill_manual(values = c(&quot;red1&quot;,&quot;skyblue1&quot;,&quot;red1&quot;,&quot;red4&quot;,&quot;skyblue4&quot;,&quot;red4&quot;)

which did not work either as it only colours by condition (only uses red1 and skyblue 1 independant of value>0)

答案1

得分: 0

你可以使用嵌套的ifelse(或if_else),但在涉及多个条件的情况下,使用dplyr中的case_when会更容易。在你的情况下:

library(dplyr)

melt_dat <- melt_dat %>% mutate("type" = case_when(value > 0 & variable == "Expression_Con_A" ~ "color1",
                                       value < 0 & variable == "Expression_Con_A" ~ "color2",
                                       value > 0 & variable == "Expression_Con_B" ~ "color3",
                                       value < 0 & variable == "Expression_Con_B" ~ "color4"))

ggplot(melt_dat, aes(x=value, y=prot_names, fill=type)) + 
  geom_bar(stat='identity', position='dodge') + 
  scale_fill_manual(values = c("red1","skyblue1","red1","red4","skyblue4","red4"))

我定义了一个新变量"type",请注意,在ggplot中,你需要将"fill"参数从"variable"更改为这个新变量。

英文:

You can use nested ifelse (or if_else), but in case of multiple conditions it'd be easier to use case_when from dplyr, In your case:

library(dplyr)

melt_dat &lt;- melt_dat %&gt;% mutate(&quot;type&quot; = case_when(value &gt; 0 &amp; variable == &quot;Expression_Con_A&quot; ~ &quot;color1&quot;,
                                       value &lt; 0 &amp; variable == &quot;Expression_Con_A&quot; ~ &quot;color2&quot;,
                                       value &gt; 0 &amp; variable == &quot;Expression_Con_B&quot; ~ &quot;color3&quot;,
                                       value &lt; 0 &amp; variable == &quot;Expression_Con_B&quot; ~ &quot;color4&quot;))

ggplot(melt_dat, aes(x=value, y=prot_names, fill=type)) + 
  geom_bar(stat=&#39;identity&#39;, position=&#39;dodge&#39;) + 
  scale_fill_manual(values = c(&quot;red1&quot;,&quot;skyblue1&quot;,&quot;red1&quot;,&quot;red4&quot;,&quot;skyblue4&quot;,&quot;red4&quot;))

I defined a new variable "type", and note that in the ggplot you've to change the "fill" argument from "variable" to this new variable.

huangapple
  • 本文由 发表于 2023年3月7日 18:16:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75660636.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定