Eric Green
Eric Green

Reputation: 7735

use ifelse in aes_string to color line

How would I convert the logical 'slope > 0' for color into a more complex conditional?

If slope>0, then red line. If slope==0, then blue line. If slope<0, then black line.

# setup
library(dplyr)
library(ggplot2)
library(lazyeval)
set.seed(205)
dat = data.frame(t=rep(1:2, each=10), 
                 pairs=rep(1:10,2), 
                 value=rnorm(20))
dat$value[dat$pairs==1] <- 1 # forgot to set one pair to slope==0


# function
plotFun <- function(df, groupBy, dv, time) {
  ggplot(df %>% group_by_(groupBy) %>%
           mutate_(slope = interp(~(dv2[time2==2] - dv2[time2==1])/(2-1),
                                  dv2=as.name(dv), 
                                  time2=as.name(time))),
         aes_string(time, dv, group = groupBy, 
                    colour = 'slope > 0')) +
    scale_colour_manual(values=c("red", "black")) +
    geom_point() +
    geom_line() +
    stat_summary(fun.y=mean,geom="line",lwd=2,aes(group=1))
}

# plot
plotFun(dat, "pairs", "value", "t")

Upvotes: 0

Views: 1305

Answers (2)

Eric Green
Eric Green

Reputation: 7735

@lukeA's comment worked for me:

# setup
library(dplyr)
library(ggplot2)
library(lazyeval)
set.seed(205)
dat = data.frame(t=rep(1:2, each=10), 
                 pairs=rep(1:10,2), 
                 value=rnorm(20))
dat$value[dat$pairs==1] <- 1 # forgot to set one pair to slope==0


# function
plotFun <- function(df, groupBy, dv, time) {
  ggplot(df %>% group_by_(groupBy) %>%
           mutate_(slope = interp(~(dv2[time2==2] - dv2[time2==1])/(2-1),
                                  dv2=as.name(dv), 
                                  time2=as.name(time))),
         aes_string(time, dv, group = groupBy, 
                    colour = ifelse(slope>0,"blue",         
                             ifelse(slope==0,"black","red"))) +
    scale_color_identity() +
    geom_point() +
    geom_line() +
    stat_summary(fun.y=mean,geom="line",lwd=2,aes(group=1))
}

# plot
plotFun(dat, "pairs", "value", "t")

Upvotes: 0

MarBlo
MarBlo

Reputation: 4524

I am not sure why you make a separate function for this. I would do it like this

library(dplyr)
library(ggplot2)
#library(lazyeval)
set.seed(205)
dat = data.frame(t=rep(1:2, each=10), 
                 pairs=rep(1:10,2), 
                 value=rnorm(20))

dd <- dat %>% group_by(pairs) %>% mutate(sl=(value[t==2]-value[t==1]))
dd <- as.data.frame(dd)
ggplot(dd, aes(x=t, y=value, group=pairs)) +
  geom_point() +
  geom_line(aes(colour=ifelse(sl>0, "red", ifelse(sl==0,"blue", "black")))) +
  theme(legend.title=element_blank())

I have added one column for the slope, calculated from the values grouped by pairs and used the group-method in ggplot. The condition for the colors I put in the aesthetic for the line. Because the original legend title gets too long because of the if-statements I switched it off.

Hope that helped.

Upvotes: 1

Related Questions