Question

I am trying to create a scatterplot and color the points within the specified ranges differently. I feel as though this chain should work, where I state the condition and the desired color in brackets.

Can anyone spot an error in my approach? or potentially the syntax?

plot(x, y, xlab="chr X position (Mb)",
     ylab="Diversity", pch=16, cex=0.7,
     col=if(x < 4), {"red"}
          else {
            if((x>3)&(x<89)) {"black"}
            else {
              if((x>88)&(x<94)) {"blue"}
              }
            else {
              if((x>93)&(x<155)) {"black"}
              }
            else {
              if(x>154) {"purple"}
              }
            }
Was it helpful?

Solution 2

Here's a solution using ifelse

col = ifelse(x<4, "red",
       ifelse(x>3 & x<89 | x>93 & x<155, "black",
              ifelse(x>88 & x<94, "blue", "purple")))

You need ifelse becase ifelse is vectorized, if is not, therefore ifelse will check each element in your vector and filled with the corresponding color, while if only checks for the first element.

A simple example to note this:

x <- 1:6  # a sample vector

# using `if` to check condition and assigning a value, it'll fail 
if(x<4){
  "red"
} else {
  "other color"
}

# suing `ifelse` for the same task. It'll win
ifelse(x<4, "red", "other color")

from the helpfile

ifelse returns a value with the same shape as test which is filled with elements selected from either yes or no depending on whether the element of test is TRUE or FALSE

OTHER TIPS

Your code is ugly! Use cut to convert your numeric values into a categorical 'factor' object, then set the colours.

> x=sample(1:20)
> x
 [1]  5  1  9 17  2  6  4  3  8 13 16 10 11 20 18 19 12 14  7 15
> f = cut(x,breaks=c(0,5,13,21)) # choose your breaks here
> f
 [1] (0,5]   (0,5]   (5,13]  (13,21] (0,5]   (5,13]  (0,5]   (0,5]   (5,13] 
[10] (5,13]  (13,21] (5,13]  (5,13]  (13,21] (13,21] (13,21] (5,13]  (13,21]
[19] (5,13]  (13,21]
Levels: (0,5] (5,13] (13,21]
> levels(f)=c("red","green","purple")
> plot(x,col=as.character(f),pch=19)

That should plot the low points in red, the middle in green, the top in purple.

For extra points, write a function that takes your values, your breaks, and a vector of colours and does the colour mapping for you. Then you just do:

> plot(x, col=colourMap(x,breaks = c(0,5,13,21), colours = c("red","green","purple")))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top