This can be done by splitting your data frame with split and operating on each subset with the lapply function. Let's assume you wanted to compute the maximum ratio of sepal length to petal length for each species in the iris dataset. You could do this with:
data(iris)
unlist(lapply(split(iris, iris$Species),
              function(x) max(x$Sepal.Length / x$Petal.Length)))
#     setosa versicolor  virginica 
#   4.833333   1.700000   1.352941 
If you wanted to return multiple values for each subset, you can slightly modify the approach:
do.call(rbind, lapply(split(iris, iris$Species),
                      function(x) data.frame(max.ratio = max(x$Sepal.Length / x$Petal.Length),
                                             min.ratio = min(x$Sepal.Length / x$Petal.Length))))
#            max.ratio min.ratio
# setosa      4.833333  2.526316
# versicolor  1.700000  1.176471
# virginica   1.352941  1.050000
This approach is called split-apply-combine.