Shaolin R
Shaolin R

Reputation: 35

R - How to conditionally color the values of a data.frame and make a plot

I have this dataframe created with the function table.CalendarReturns from the PerfomanceAnalytics package (the rownames are the years and the colnames are the months ):

tabRet

> 
 gen  feb  mar  apr  may  jun  jul  aug sep  oct nov  dec System
 2004 0.0  3.5  2.9  2.0  1.1 -0.4  1.2 3.3  0.9 1.8  3.0 -0.6   20.1
 2005 1.6  2.3 -1.2  4.0  0.0  1.6 -1.4 2.4  0.7 2.9  2.9  0.4   17.3
 2006 0.8  2.7  0.3  1.4  6.2 -2.6  2.1 2.8  0.5 0.3  0.7  3.1   19.6
 2007 1.3  0.1  1.4  0.1  1.6 -1.0  1.0 1.5 -0.7 1.0  1.3 -0.7    7.0
 2008 1.4 -1.2  2.2  1.2 -0.3 -0.8  2.2 0.4  1.1 0.1  4.4 -1.3    9.7
 2009 4.8  3.2  1.6  3.5  0.7  1.7  2.1 2.2  2.5 1.9  1.5  2.8   32.4
 2010 3.5  0.5  0.4  1.3  1.8  3.8  3.7 3.0  1.1 1.2  3.9  3.4   31.2    
 2011 4.3  2.1  1.6 -0.8  3.9  1.5  4.0 5.4  2.3 2.9  0.2  1.5   33.0
 2012 1.1  1.9 -0.1  2.3  1.0  3.6  1.5 0.7  0.0 1.5  1.2  0.5   16.3
 2013 0.8  2.5  1.2  1.4  0.0  1.7  2.3 1.7  0.5 0.2  1.3  0.6   15.1
 2014 0.1  0.7  0.3 -0.7  1.0  1.0  0.2 0.9 -0.7 2.3  1.4  1.4    8.2
 2015 2.3  1.0  1.1  3.1  4.5 -0.7 -0.3 2.3  2.4 0.4 -1.3  1.0   16.7
 2016 2.1  2.5  0.9  1.0  0.2   NA   NA  NA   NA  NA   NA   NA    7.0

I would like to create a plot with something like this for the colors of the numbers: ifelse(values< 0,'red','black').

I tried with the addtable2plot function, from the plotrix package with bad results. Any tips about this problem? Thank you in advance guys.

EDIT: I need something like this but with the negative numbers in red:

textplot(Hmisc::format.df(tabRet, na.blank=TRUE, numeric.dollar=FALSE, cdec=rep(1,dim(tabRet)[2])), rmar = 0.8, cmar = 1, max.cex=.9, halign = "center", valign = "center", row.valign="center", wrap.rownames=20, wrap.colnames=10, col.colnames="Darkblue",col.rownames="Darkblue", mar = c(0,0,4,0)+0.1) title(main="Calendar Monthly Returns",col.main="Darkblue", cex.main=1)

PLOT

Upvotes: 2

Views: 7504

Answers (4)

edgar barahona
edgar barahona

Reputation: 1

I do not know if I found the solution, I hope this code will serve you this code receives a data.frame and converts it into conditional format, the value of the cells is shown in the columns

[Data i a data.frame][1] [1]: https://i.sstatic.net/jETa8.png

pmensual <- readXL("D:precipitacion mensual 
2021/Base de Datos Precipitación mensual .xls",
                   rownames=FALSE, header=TRUE, na="", sheet="Preci_mes", 
                   stringsAsFactors=TRUE)

nba.m <- melt(pmensual)
nba.s <- ddply(nba.m, .(variable), transform)
ggplot(nba.s, aes(variable, Nombre)) + 
   geom_tile(aes(fill = value), colour = "white") +
   #scale_colour_gradientn(colours = c("blue", "green", "red"))+
   scale_fill_gradient2(low = "white", high = "red", mid = "blue", midpoint = 400) +
   geom_text(aes(label = round(value, 1)), size= 3.5, vjust = 0.4)+
   scale_x_discrete("Mes", expand = c(0, 0)) + 
   scale_y_discrete("Estaciones", expand = c(0, 0)) + 
   theme( legend.position="bottom", legend.title=element_text(), panel.background = 
   element_rect(fill = "white", colour = "gray"),
          panel.grid.major = element_line(colour = "gray"))+
   
   labs(title = "Mapa de Calor Precipitaciones en la zona de Estudio",
        subtitle = "Precipitacion Acumulada al mes" , fill = "Precipitacion mm" )

[result ][2] [2]: https://i.sstatic.net/FVYV4.png

Upvotes: 0

rafa.pereira
rafa.pereira

Reputation: 13807

Here is a solution using geom_tile{ggplot2} with a reproducible example:

# load libraries
  library(ggplot2)
  library(ggthemes)
  library(data.table)
  library(PerformanceAnalytics)

# load data
  data(managers)
  df <- as.data.frame(t(table.CalendarReturns(managers[,c(1,7,8)])))

#  Convert row names into first column
  df <- setDT(df, keep.rownames = TRUE)[]
  setnames(df, "rn", "month")

# reshape your data
   df2 <- melt(df, id.var = "month")

# Plot
ggplot(df2, aes(x=month, y=variable)) + 
      geom_tile( fill= "white", color = "white") +
      geom_text(aes(label=value, color= value < 0)) +
      scale_color_manual(guide=FALSE, values=c("red", "black")) +
      theme_pander( ) +
      theme(axis.text = element_text(face = "bold")) +
      ggtitle("Calendar Monthly Returns")

enter image description here

You can also choose to fill the tiles instead of the text.

ggplot(df2) +
  geom_tile( aes(x=month , y=variable, fill= value < 0), color = "gray70", alpha = 0.7) +
  scale_fill_manual(guide=FALSE, values=c("red", "black")) +
  theme_pander()

enter image description here

In any case, this answer provides a general approach to conditional colors in ggplot.

ggplot(mtcars, aes(wt, mpg)) +
  geom_point( aes(color= ifelse(mpg > 20, "A", "B")) )  +
  scale_color_manual(guide=FALSE, values=c("red", "black")) 

enter image description here

You can also do this using base:

plot(mtcars$wt, mtcars$mpg, 
     col=ifelse( mtcars$mpg > 20 ,"red", "black") )

Upvotes: 2

Marat Talipov
Marat Talipov

Reputation: 13304

Simply add col.data=ifelse(tabRet<0,'red','black'), after col.rownames="Darkblue", to your code

Upvotes: 2

Gaurav Taneja
Gaurav Taneja

Reputation: 1094

If this is what you are looking for:

require(tidyr)
require(ggplot2)
d<-data.table(gen=seq(2004,2016,1),Jan=round(rnorm(13)),Feb=round(rnorm(13)),Mar=round(rnorm(13)))
gd<-gather(d,key=gen)
gd$col<-ifelse(gd$value<0.5,"1","0")
ggplot(data=gd,aes(x=gen,y=value,color=col))+geom_tile(aes(fill=col))+
  scale_fill_manual(values=c("red","black"))

enter image description here

Upvotes: 0

Related Questions