How to scale points in R plot? - r

I have 40 pairs of birds with each male and female scored for their colour. The colour score is a categorical variable (range of 1 to 9). I would like to plot the frequency of the number of males and female pairs colour combinations. I have to created a 'table' with the number of each combination (1/1, 1/2, 1/3, ... 9/7, 9/8, 9/9), then converted it to a vector called 'Colour_Count'. I would like to use 'Colour_Count' for the 'cex' parameter in the 'plot' to scale the size of each combination of colours. This does not work because of the order the data is read from the table. How do I create a vector with the frequency of each colour combination to scale my plot points?
See data and code below:
## Dataset pairs of males and females and their colour classes
Pair_Colours <- structure(list(Male = c(7, 6, 4, 6, 8, 8, 5, 6, 6, 8, 6, 6, 5,
7, 9, 5, 8, 7, 5, 5, 4, 6, 7, 7, 3, 6, 5, 4, 7, 4, 3, 9, 4, 4,
4, 4, 9, 6, 6, 6), Female = c(9, 8, 8, 9, 3, 6, 8, 5, 8, 9, 7,
3, 6, 5, 8, 9, 7, 3, 6, 4, 4, 4, 8, 8, 6, 7, 4, 2, 8, 9, 5, 6,
8, 8, 4, 4, 5, 9, 7, 8)), .Names = c("Male", "Female"), class = "data.frame", row.names = c(NA,
40L))
Pair_Colours[] <- as.data.frame(lapply(Pair_Colours, factor, levels=1:9))
## table of pair colour values (colours 1 to 9 - categoricial variable)
table(Pair_Colours$Male, Pair_Colours$Female)
Colour_Count <- as.vector(table(Pair_Colours$Male, Pair_Colours$Female)) #<- the problem occurs here
## plot results to visisually look for possible assortative mating by colour
op<-par(mfrow=c(1,1), oma=c(2,4,0,0), mar=c(4,5,1,2), pty = "s")
plot(1,1, xlim = c(1, 9), ylim = c(1, 9), type="n", xaxt = "n", yaxt = "n", las=1, bty="n", cex.lab = 1.75, cex.axis = 1.5, main = NULL, xlab = "Male Colour", ylab = "Female Colour", pty = "s")
axis(1, at = seq(1, 9, by = 1), labels = T, cex.lab = 1.5, cex.axis = 1.5, tick = TRUE, tck = -0.015, lwd = 1.25, lwd.ticks = 1.25)
axis(2, at = seq(1, 9, by = 1), labels = T, cex.lab = 1.5, cex.axis = 1.5, tick = TRUE, tck = -0.015, lwd = 1.25, lwd.ticks = 1.25, las =2)
points(Pair_Colours$Male, Pair_Colours$Female, pch = 21, cex = Colour_Count, bg = "darkgray", col = "black", lwd = 1)

You can summarise your data with function ddply() of library plyr and then use this new data frame to plot your data. Counts are in column V1 of new data frame.
library(plyr)
df<-ddply(Pair_Colours,.(Male,Female),nrow)
df
Male Female V1
1 3 5 1
2 3 6 1
3 4 2 1
4 4 4 3
points(df$Male, df$Female, pch = 21, cex = df$V1,
bg = "darkgray", col = "black", lwd = 1)
UPDATE - solution using aggregate
Other possibility is to use function aggregate(). First, add new column N that contains just values 1. Then with aggregate() sum N values for each Male and Female combination.
Pair_Colours$N<-1
aggregate(N~Male+Female,data=Pair_Colours,FUN=sum)
Male Female N
1 4 2 1
2 6 3 1
3 7 3 1
4 8 3 1
5 4 4 3

Related

How to obtain the tree from igraph object in R?

I have a random directed weighted graph gg, it has the next structure:
gg <-
structure(list(10, TRUE, c(0, 0, 1, 2, 2, 5, 5, 6, 6, 6, 6, 9,
9, 9, 9, 9), c(6, 9, 3, 0, 5, 3, 7, 1, 3, 5, 8, 2, 4, 6, 7, 8
), c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), c(3,
7, 11, 2, 5, 8, 12, 4, 9, 0, 13, 6, 14, 10, 15, 1), c(0, 2, 3,
5, 5, 5, 7, 11, 11, 11, 16), c(0, 1, 2, 3, 6, 7, 9, 11, 13, 15,
16), list(c(1, 0, 1), structure(list(), .Names = character(0)),
structure(list(name = c("C", "D", "I", "J", "K", "N", "O",
"Q", "S", "T"), color = c("yellow", "red", "red", "red",
"red", "red", "green", "red", "red", "green")), .Names = c("name",
"color")), structure(list(weight = c(0.5, 0.5, 1, 0.333333333333333,
0.333333333333333, 0.333333333333333, 0.333333333333333,
0.25, 0.25, 0.25, 0.25, 0.2, 0.2, 0.2, 0.2, 0.2)), .Names = "weight")),
<environment>), class = "igraph")
I need to find all walks from the root (yellow node) to leaves (red nodes). Leaves defined by (a) edge direction and (b) the distance -- from the root to the leave should be two edges only.
In my case, the root is C and leaves should be D, J, N, S, I, K, Q.
I tried to define the (a) condition only.
root <- "C"
leaves = which(degree(gg, v = V(gg), mode = "out")==0, useNames = T)
leaves
# J K Q S
# 4 5 8 9
plot(gg, layout = layout.reingold.tilford(gg, root=root),
edge.arrow.size=0.2, edge.curved=T,
edge.label = round(E(gg)$weight,2))
Question. How to define the (b) condition and add to leaves set D, N, I, K nodes?
Here's one way to do it: use shortest_paths to get all the vertices that are exactly two edges from the root node.
two.edges.from.root = unlist(sapply(shortest_paths(gg,
from = as.numeric(V(gg)["C"]),
mode = "out")$vpath,
function(x) { if(length(x) == 3) { x[3] } }))

plot (ggplot ?) smooth + color area between 2 curves

I have a question for you please :
My data :
Nb_obs <- as.vector(c( 2, 0, 6, 2, 7, 1, 8, 0, 2, 1, 1, 3, 11, 5, 9, 6, 4, 0, 7, 9))
Nb_obst <- as.vector(c(31, 35, 35, 35, 39, 39, 39, 39, 39, 41, 41, 42, 43, 43, 45, 45, 47, 48, 51, 51))
inf20 <- as.vector(c(2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 3, 5, 4))
sup20 <- as.vector(c(3, 4, 4, 4, 5, 4, 4, 5, 4, 4, 5, 5, 5, 6, 5, 6, 6, 5, 7, 6))
inf40 <- as.vector(c(1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 4, 3))
sup40 <- as.vector(c(4, 5, 5, 5, 6, 5, 5, 6, 5, 5, 6, 6, 6, 7, 6, 7, 7, 7, 9, 7))
inf60 <- as.vector(c(1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 2))
sup60 <- as.vector(c(5, 6, 6, 6, 8, 7, 7, 7, 7, 7, 7, 7, 8, 9, 8, 9, 9, 9, 11, 9))
inf90 <- as.vector(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1))
sup90 <- as.vector(c(10, 11, 11, 11, 15, 13, 13, 14, 12, 13, 13, 13, 14, 17, 15, 17, 17, 16, 21, 18))
data <- cbind.data.frame(Nb_obs, Nb_obst, inf20, sup20, inf40, sup40, inf60 , sup60, inf90 , sup90)
My plot :
plot(data$Nb_obst, data$Nb_obs, type = "n", xlab = "Number obst", ylab = "number obs", ylim = c(0, 25))
lines(data$Nb_obst, data$inf20, col = "dark red")
lines(data$Nb_obst, data$sup20, col = "dark red")
lines(data$Nb_obst, data$inf40, col = "red")
lines(data$Nb_obst, data$sup40, col = "red")
lines(data$Nb_obst, data$inf60, col = "dark orange")
lines(data$Nb_obst, data$sup60, col = "dark orange")
lines(data$Nb_obst, data$inf90, col = "yellow")
lines(data$Nb_obst, data$sup90, col = "yellow")
My question :
There are two things I'd like to do (and so I think it could be done by ggplot):
In the idea of the graph at the top, the "inf" and "sup" are limits of my model in the IC 20%, then 40%, then 60%, and finally 90%. I would first like to smooth each curve, and then I would like to color the surface between two curves of the same IC, for example that the surface between "data$inf90" and "data$sup90" is yellow, the area between "data$inf60" and "data$60" is orange, etc. And I would like to superimpose each of these colored surfaces + put the good legend please.
Thanks for your help !
Cool question since I had to give myself a crash course in using LOESS for ribbons!
First thing I'm doing is getting the data into a long shape, since that's what ggplot will expect, and since your data has some characteristics that are kind of hidden within values. For example, if you gather into a long shape and have, say a column key, with a value of "inf20" and another of "sup20", those hold more information than you currently have access to, i.e. the measure type is either "inf" or "sup", and the level is 20. You can extract that information out of that column to get columns of measure types ("inf" or "sup") and levels (20, 40, 60, or 90), then map aesthetics onto those variables.
So here I'm getting the data into a long shape, then using spread to make columns of inf and sup, because those will become ymin and ymax for the ribbons. I made level a factor and reversed its levels, because I wanted to change the order of the ribbons being drawn such that the narrow one would come up last and be drawn on top.
library(tidyverse)
data_long <- data %>%
as_tibble() %>%
gather(key = key, value = value, -Nb_obs, -Nb_obst) %>%
mutate(measure = str_extract(key, "\\D+")) %>%
mutate(level = str_extract(key, "\\d+")) %>%
select(-key) %>%
group_by(level, measure) %>%
mutate(row = row_number()) %>%
spread(key = measure, value = value) %>%
ungroup() %>%
mutate(level = as.factor(level) %>% fct_rev())
head(data_long)
#> # A tibble: 6 x 6
#> Nb_obs Nb_obst level row inf sup
#> <dbl> <dbl> <fct> <int> <dbl> <dbl>
#> 1 0 35 20 2 2 4
#> 2 0 35 40 2 2 5
#> 3 0 35 60 2 1 6
#> 4 0 35 90 2 0 11
#> 5 0 39 20 8 3 5
#> 6 0 39 40 8 2 6
ggplot(data_long, aes(x = Nb_obst, ymin = inf, ymax = sup, fill = level)) +
geom_ribbon(alpha = 0.6) +
scale_fill_manual(values = c("20" = "darkred", "40" = "red",
"60" = "darkorange", "90" = "yellow")) +
theme_light()
But it still has the issue of being jagged, so for each level I predicted smoothed values of both inf and sup versus Nb_obst using loess. group_by and do yield a nested data frame, and unnest pulls it back out into a workable form. Feel free to adjust the span parameter, as well as other loess.control parameters that I know very little about.
data_smooth <- data_long %>%
group_by(level) %>%
do(Nb_obst = .$Nb_obst,
inf_smooth = predict(loess(.$inf ~ .$Nb_obst, span = 0.35), .$Nb_obst),
sup_smooth = predict(loess(.$sup ~ .$Nb_obst, span = 0.35), .$Nb_obst)) %>%
unnest()
head(data_smooth)
#> # A tibble: 6 x 4
#> level Nb_obst inf_smooth sup_smooth
#> <fct> <dbl> <dbl> <dbl>
#> 1 90 35 0 11.
#> 2 90 39 0 13.4
#> 3 90 48 0.526 16.7
#> 4 90 39 0 13.4
#> 5 90 41 0 13
#> 6 90 41 0 13
ggplot(data_smooth, aes(x = Nb_obst, ymin = inf_smooth, ymax = sup_smooth, fill = level)) +
geom_ribbon(alpha = 0.6) +
scale_fill_manual(values = c("20" = "darkred", "40" = "red",
"60" = "darkorange", "90" = "yellow")) +
theme_light()
Created on 2018-05-26 by the reprex package (v0.2.0).
This produces the plot with shaded areas using base R graphics.
The trick is to pair the x values with the y values.
plot(data$Nb_obst, data$Nb_obs, type = "n", xlab = "Number obst", ylab = "number obs", ylim = c(0, 25))
lines(data$Nb_obst, data$inf20, col = "dark red")
lines(data$Nb_obst, data$sup20, col = "dark red")
lines(data$Nb_obst, data$inf40, col = "red")
lines(data$Nb_obst, data$sup40, col = "red")
lines(data$Nb_obst, data$inf60, col = "dark orange")
lines(data$Nb_obst, data$sup60, col = "dark orange")
lines(data$Nb_obst, data$inf90, col = "yellow")
lines(data$Nb_obst, data$sup90, col = "yellow")
with(data, polygon(c(Nb_obst, rev(Nb_obst)), c(inf90, rev(sup90)), col = "yellow"))
with(data, polygon(c(Nb_obst, rev(Nb_obst)), c(inf60, rev(sup60)), col = "dark orange"))
with(data, polygon(c(Nb_obst, rev(Nb_obst)), c(inf40, rev(sup40)), col = "red"))
with(data, polygon(c(Nb_obst, rev(Nb_obst)), c(inf20, rev(sup20)), col = "dark red"))
The code for a ggplot graph is a bit longer. There is a function geom_ribbon perfect for this.
g <- ggplot(data)
g + geom_ribbon(aes(x = Nb_obst, ymin = sup60, ymax = sup90), fill = "yellow") +
geom_ribbon(aes(x = Nb_obst, ymin = sup40, ymax = sup60), fill = "dark orange") +
geom_ribbon(aes(x = Nb_obst, ymin = sup20, ymax = sup40), fill = "red") +
geom_ribbon(aes(x = Nb_obst, ymin = inf20, ymax = sup20), fill = "dark red") +
geom_ribbon(aes(x = Nb_obst, ymin = inf40, ymax = inf20), fill = "red") +
geom_ribbon(aes(x = Nb_obst, ymin = inf60, ymax = inf40), fill = "dark orange") +
geom_ribbon(aes(x = Nb_obst, ymin = inf90, ymax = inf60), fill = "yellow")
Data.
I will redo your dataset, simplifying its creation. You don't need as.vector and if you are creating a data.frame there is no need for the data.frame method of cbind, data.frame(.) is enough.
Nb_obs <- c( 2, 0, 6, 2, 7, 1, 8, 0, 2, 1, 1, 3, 11, 5, 9, 6, 4, 0, 7, 9)
Nb_obst <- c(31, 35, 35, 35, 39, 39, 39, 39, 39, 41, 41, 42, 43, 43, 45, 45, 47, 48, 51, 51)
inf20 <- c(2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 3, 5, 4)
sup20 <- c(3, 4, 4, 4, 5, 4, 4, 5, 4, 4, 5, 5, 5, 6, 5, 6, 6, 5, 7, 6)
inf40 <- c(1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 3, 4, 3)
sup40 <- c(4, 5, 5, 5, 6, 5, 5, 6, 5, 5, 6, 6, 6, 7, 6, 7, 7, 7, 9, 7)
inf60 <- c(1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 2)
sup60 <- c(5, 6, 6, 6, 8, 7, 7, 7, 7, 7, 7, 7, 8, 9, 8, 9, 9, 9, 11, 9)
inf90 <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1)
sup90 <- c(10, 11, 11, 11, 15, 13, 13, 14, 12, 13, 13, 13, 14, 17, 15, 17, 17, 16, 21, 18)
data <- data.frame(Nb_obs, Nb_obst, inf20, sup20, inf40, sup40, inf60 , sup60, inf90 , sup90)

Passing smooth line through all data points with more than 50 points

I have data that looks like:
year mean.streak
1958 2.142857
1959 3.066667
1960 2.166667
1961 2.190476
The code for my plot with localized regression looks like:
ggplot(aes(x = year, y = mean.streak, color = year), data = streaks)+
geom_point(color = 'black')+
geom_smooth(method = 'loess')
and outputs:
I'd like to capture the somewhat sinusoidal pattern of the data by passing a smooth line through all of the data points, rather than the typical jagged geom_line. I tried polynomial interpolation by writing:
ggplot(df)+
geom_point(aes(x = year, y = mean.streak, colour = year), size = 3) +
stat_smooth(aes(x = year, y = mean.streak), method = "lm",
formula = y ~ poly(x, 57), se = FALSE)
Taken from this thread. But I get the error:
Warning message:
Computation failed in `stat_smooth()`:
'degree' must be less than number of unique points
seemingly because there are too many datapoints, as this answer seems to indicate.
Is there a way to pass a smooth line through all the data with 59 data points?
Full data is:
structure(list(year = 1958:2016, mean.streak = c(2.14285714285714,
3.06666666666667, 2.16666666666667, 2.19047619047619, 2.35, 2.42857142857143,
2.28571428571429, 1.92592592592593, 1.69230769230769, 2.61111111111111,
3, 2.94117647058824, 2.2, 2.5, 2.13636363636364, 1.76923076923077,
1.36111111111111, 1.41176470588235, 1.76, 2, 2.63157894736842,
2.08695652173913, 2.86666666666667, 2.125, 3, 3.125, 2.57894736842105,
1.84, 1.46666666666667, 1.7037037037037, 1.625, 1.67741935483871,
1.84, 1.6, 3, 3.11111111111111, 3.66666666666667, 4.18181818181818,
2.85714285714286, 3.66666666666667, 2.66666666666667, 2.92857142857143,
3.1875, 2.76923076923077, 5.375, 5.18181818181818, 4.08333333333333,
6.85714285714286, 2.77777777777778, 2.76470588235294, 3.15384615384615,
3.83333333333333, 3.06666666666667, 3.07692307692308, 4.41666666666667,
4.9, 5.22222222222222, 5, 5.27272727272727), median.streak = c(1,
3, 1.5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 2,
2, 3, 2, 2, 2.5, 2, 2, 1, 1, 1, 1, 1, 1, 1.5, 2, 4, 4, 1, 3,
2, 2.5, 2, 2, 5.5, 4, 2.5, 9, 2, 2, 2, 1.5, 2, 3, 2.5, 4.5, 4,
5, 4), max.streak = c(6, 6, 9, 7, 5, 5, 7, 4, 3, 7, 9, 7, 6,
6, 6, 4, 3, 4, 4, 10, 8, 6, 6, 5, 10, 8, 5, 6, 3, 4, 4, 4, 4,
5, 8, 8, 11, 8, 8, 11, 10, 5, 12, 7, 10, 12, 12, 10, 7, 10, 10,
14, 9, 7, 9, 12, 10, 14, 12), mean.std = c(-0.73762950487994,
-0.480997734887942, -0.517355702126398, -0.387678832192802, -0.315808940316265,
-0.455313725347534, -0.520453518496716, -0.598412265824216, -0.523171795723798,
-0.62285788065637, -0.54170040191883, -0.590289727314622, -0.468222025966258,
-0.639180735884434, -0.656427002478427, -0.565745564840106, -0.473399411312895,
-0.564475310127763, -0.493531273810312, -0.543209721496256, -0.640240670332106,
-0.510337503791441, -0.596096374402028, -0.504696265560619, -0.620412635042488,
-0.497008319856979, -0.546623513153538, -0.613345407826292, -0.564945850817486,
-0.581770706442245, -0.5709080560492, -0.627986564445679, -0.680973485641403,
-0.548092447365696, -0.554620596559388, -0.483847268000936, -0.67619820292833,
-0.613245144944101, -0.509832316970819, -0.302654541906113, -0.623276311320811,
-0.431421947082012, -0.525548788393688, -0.244995094473986, -0.412444188256097,
-0.112114155982405, -0.299486359079708, -0.300201791042539, -0.240281366191648,
-0.359719754440627, -0.511417389357902, -0.474906675611613, -0.312106332395495,
-0.449137693833681, -0.526248555772371, -0.56052848268042, -0.390017880007091,
-0.537267264953157, -0.444528236868953)), class = c("tbl_df",
"tbl", "data.frame"), .Names = c("year", "mean.streak", "median.streak",
"max.streak", "mean.std"), row.names = c(NA, -59L))
Adjust the span:
ggplot(aes(x = year, y = mean.streak, color = year), data = streaks)+
geom_point(color = 'black')+
stat_smooth(method = 'loess', span = 0.3)
Or use a spline:
library(splines)
ggplot(aes(x = year, y = mean.streak, color = year), data = streaks)+
geom_point(color = 'black')+
stat_smooth(method = 'lm', formula = y ~ ns(x, 10))
Generally, you don't want to fit an extremely high-degree polynomial. Such fits look awful. It would be much better to fit an actual time series model to your data:
library(forecast)
library(zoo)
ggplot(aes(x = year, y = mean.streak, color = year), data = streaks)+
geom_point(color = 'black')+
geom_line(data = data.frame(year = sort(streaks$year),
mean.streak = fitted(auto.arima(zoo(streaks$mean.streak,
order.by = streaks$year)))),
show.legend = FALSE)

Grey Background in R When Using qcc (quality control charts) Plot

I'm having a problem where my graph is always on a light grey background which looks awful in LaTeX. I've tried using par(bg=NA), par(bg="white") which is what everyone suggests but that literally does nothing...
Here's the code:
# install.packages('qcc')
library(qcc)
nonconforming <- c(3, 4, 6, 5, 2, 8, 9, 4, 2, 6, 4, 8, 0, 7, 20, 6, 1, 5, 7)
samplesize <- rep(50, 19)
control <- qcc(nonconforming, type = "p", samplesize, plot = "FALSE")
warn.limits <- limits.p(control$center, control$std.dev, control$sizes, 2)
par(mar = c(5, 3, 1, 3), bg = "blue")
plot(control, restore.par = FALSE, title = "P Chart for Medical Insurance Claims",
xlab = "Day", ylab = "Proportion Defective")
abline(h = warn.limits, lty = 3, col = "blue")
v2 <- c("LWL", "UWL") # the labels for warn.limits
mtext(side = 4, text = v2, at = warn.limits, col = "blue", las = 2)
Check out ?qcc.options() -- specifically, the bg.margin option. The following will change your plot to have a lightgreen background (note: probably not a good choice for LaTeX, but it illustrates the point):
library(qcc)
nonconforming <- c(3, 4, 6, 5, 2, 8, 9, 4, 2, 6, 4, 8, 0, 7, 20, 6, 1, 5, 7)
samplesize <- rep(50, 19)
old <- qcc.options() # save the original options
qcc.options(bg.margin = "lightgreen")
par(mar = c(5, 3, 1, 3))
control <- qcc(nonconforming, type = "p", samplesize, plot = "FALSE")
warn.limits <- limits.p(control$center, control$std.dev, control$sizes, 2)
plot(control, restore.par = FALSE, title = "P Chart for Medical Insurance Claims",
xlab = "Day", ylab = "Proportion Defective")
abline(h = warn.limits, lty = 3, col = "blue")
v2 <- c("LWL", "UWL") # the labels for warn.limits
mtext(side = 4, text = v2, at = warn.limits, col = "blue", las = 2)
qcc.options(old) # reset the old options

how to make barplot bars same size in plot window in R using barplot function

I would like to plot 3 plots in the same window. Each will have a different amount of bar plots. How could I make them all the same size and close together (same distance from each other) without doing NAs in the smaller barplots. example code below. I do want to point out my real data will be plotting numbers from dataframes$columns not a vector of numbers as shown below. I am sure there is magic way to do this but cant seem to find helpful info on the net. thanks
pdf(file="PATH".pdf");
par(mfrow=c(1,3));
par(mar=c(9,6,4,2)+0.1);
barcenter1<- barplot(c(1,2,3,4,5));
mtext("Average Emergent", side=2, line=4);
par(mar=c(9,2,4,2)+0.1);
barcenter2<- barplot(c(1,2,3));
par(mar=c(9,2,4,2)+0.1);
barcenter3<- barplot(c(1,2,3,4,5,6,7));
Or would there be a way instead of using the par(mfrow....) to make a plot window, could we group the barcenter data on a single plot with an empty space between the bars? This way everything is spaced and looks the same?
Using the parameters xlim and width:
par(mfrow = c(1, 3))
par(mar = c(9, 6, 4, 2) + 0.1)
barcenter1 <- barplot(c(1, 2, 3, 4, 5), xlim = c(0, 1), width = 0.1)
mtext("Average Emergent", side = 2, line = 4)
par(mar = c(9, 2, 4, 2) + 0.1)
barcenter2 <- barplot(c(1, 2, 3), xlim = c(0, 1), width = 0.1)
par(mar = c(9, 2, 4, 2) + 0.1)
barcenter1 <- barplot(c(1, 2, 3, 4, 5, 6, 7), xlim = c(0, 1), width = 0.1)
Introducing zeroes:
df <- data.frame(barcenter1 = c(1, 2, 3, 4, 5, 0, 0),
barcenter2 = c(1, 2, 3, 0, 0, 0, 0),
barcenter3 = c(1, 2, 3, 4, 5, 6, 7))
barplot(as.matrix(df), beside = TRUE)
With ggplot2 you can get something like this:
df <- data.frame(x=c(1, 2, 3, 4, 5,1, 2, 3,1, 2, 3, 4, 5, 6, 7),
y=c(rep("bar1",5), rep("bar2",3),rep("bar3",7)))
library(ggplot2)
ggplot(data=df, aes(x = x, y = x)) +
geom_bar(stat = "identity")+
facet_grid(~ y)
For the option you mentioned in your second comment you would need:
x <- c(1, 2, 3, 4, 5, NA, 1, 2, 3, NA, 1, 2, 3, 4, 5, 6, 7)
barplot(x)

Resources