3

Neither this post nor this post apply to my case.

Assume:

set.seed(42)
x<-rep(c("A","B","C"), c(3,4,1))
y<-rep(c("V","W"),c(5,3))
z<-rnorm(8,-2,1)
df<-data.frame(x,y,z)
boxplot(z~x+y,df)

I want my plot to include groups with more than, say, one element. This means that I want my plot show only A.V, B.V and B.W. Furthermore, since my graph has about 70 groups, I don't want to do it by writing a list by hand.

Thanks

Community
  • 1
  • 1
pmjn6
  • 307
  • 1
  • 4
  • 14

2 Answers2

5

You can create a new column ('xy') using paste, create a logical index using ave for 'xy' groups having more than one elements, and then do the boxplot.

df1$xy <- factor(paste(df1$x, df1$y, sep='.'))
index <-  with(df1, ave(1:nrow(df1), xy, FUN=length))>1
boxplot(z~xy, droplevels(df1[index,]))

enter image description here

Or using ggplot

library(dplyr)
library(tidyr)
library(ggplot2)

df %>% 
   group_by(x,y) %>%
   filter(n()>1) %>%
   unite(xy, x,y) %>% 
   ggplot(., aes(xy, z))+
                geom_boxplot()
akrun
  • 874,273
  • 37
  • 540
  • 662
3

You can see if any bp$n are 0 and subset by that

set.seed(42)
df <- data.frame(x = rep(c("A","B","C"), c(3,4,1)),
                 y = rep(c("V","W"),c(5,3)),
                 z = rnorm(8,-2,1))
bp <- boxplot(z ~ x + y, df, plot = FALSE)
wh <- which(bp$n == 0)

bp[] <- lapply(bp, function(x) if (length(x)) {
  ## `bp` contains a list of boxplot statistics, some vectors and
  ## some matrices which need to be indexed accordingly
  if (!is.null(nrow(x))) x[, -wh] else x[-wh] 
  ## some of `bp` will not be present depending on how you called
  ## `boxplot`, so if that is the case, you need to leave them alone
  ## to keep the original structure so `bxp` can deal with it
  } else x)

## call `bxp` on the subset of `bp`
bxp(bp)

enter image description here

Or you can use any value you like:

wh <- which(bp$n <= 1)

bp[] <- lapply(bp, function(x) if (length(x)) {
  if (!is.null(nrow(x))) x[, -wh] else x[-wh] 
} else x)

bxp(bp)

enter image description here

rawr
  • 20,481
  • 4
  • 44
  • 78