You should always provide reproducible data with your question. It is recommended and you will get your answer faster. Here is a data set that is included in R. It consists of measurements of flowers, but it is organized similarly to yours:
data(iris)
str(iris)
# 'data.frame': 150 obs. of 5 variables:
# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
# $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
We will construct boxplots by Species
for the first measurement, Sepal.Length
. First we need the statistics:
cvs <- aggregate(Sepal.Length~Species, iris, function(x) sd(x)/mean(x)*100)
cvs
# Species Sepal.Length
# 1 setosa 7.041
# 2 versicolor 8.696
# 3 virginica 9.652
range(iris$Sepal.Length)
# [1] 4.3 7.9
We need the range in Sepal.Length
to make enough space on the plot for the statistics:
boxplot(Sepal.Length~Species, iris, ylim=c(4.1, 8.1))
par("usr")[3:4]
# [1] 3.94 8.26
The bottom of the plot is at 3.94 and the top is at 8.26 so we plot the statistics a little above the bottom or a little below the top:
text(1:3, rep(4.1, 3), round(cvs$Sepal.Length, 2))
text(1:3, rep(8.1, 3), round(cvs$Sepal.Length, 2))
You did not say where you wanted to print the values this example puts them above and below. 