Search code examples
rggplot2scatter-plotfacet-grid

ggplot facet grid within a factor


Consider data that looks like this

fitem<-rep(rep(1:16,each=3),2)
fsubs<-factor(rep(rep(paste('sub',1:3,sep=''),16),2))
ftime<-factor(as.character(rep(c('a','b'),each=48)))
fcounts<-as.numeric(round(runif(96,1,10)))
fdf<-data.frame(fsubs,fitem,fcounts,ftime)


head(df)

  fsubs fitem fcounts ftime
1  sub1     1       8     a
2  sub2     1      10     a
3  sub3     1       4     a
4  sub1     2       4     a
5  sub2     2       1     a
6  sub3     2       6     a

I would like to plot a facet grid that shows the counts for the two time points ('a','b'), subject-wise. I can't seem to figure out how to plot this in ggplot

here is my ugly attempt to do it

fdf_counts<-data.frame()
for (i in unique(fdf$fsubs)){
  fdf_counts<-append(fdf_counts,cbind(fdf%>%filter(fsubs==i,ftime=='a')%>%dplyr::select(fcounts),
                        fdf%>%filter(fsubs==i,ftime=='b')%>%dplyr::select(fcounts)))

fdf_counts<-data.frame(fdf_counts)
}

s1<-ggplot(fdf_counts,aes(x=fcounts,y=fcounts.1))+geom_point()+geom_smooth(method='lm')+labs(x='a',y='b',title='sub1')
s2<-ggplot(fdf_counts,aes(x=fcounts.2,y=fcounts.3))+geom_point()+geom_smooth(method='lm')+labs(x='a',y='b',title='sub2')
s3<-ggplot(fdf_counts,aes(x=fcounts.4,y=fcounts.5))+geom_point()+geom_smooth(method='lm')+labs(x='a',y='b',title='sub3')



plot_grid(s1,s2,s3)#from 'cowplot' package

enter image description here

How can I do this with using the original fdf data.frame? Especially as the # of subs increase

Or for example if I wanted to plot one scatter plot across all of the subs with fcounts against eachother with ftime(a) as x axis and ftime(b) as y axis?


Solution

  • Consider a merge solution with data frame by itself on fsubs and fitem (being sequential number of items per fsubs and ftime grouping). This approach allows you to keep your long, tidy data format which is ideal format for ggplot since you can then facet_grid using fsubs without iteration.

    mdf <- merge(subset(fdf, ftime=="a"), 
                 subset(fdf, ftime=="b"), 
                 by=c("fsubs", "fitem"), 
                 suffixes=c("", "_"))
    
    ggplot(mdf, aes(x=fcounts, y=fcounts_)) + 
      geom_point() + 
      geom_smooth(method='lm') +
      labs(x='a', y='b') + 
      facet_grid(~fsubs)
    

    Plot Output