Personally I would use aggregate
:
aggregate(length ~ sp, data = df, FUN= "mean" )
# by species only
# sp length
#1 1 5.0
#2 2 2.5
aggregate(length ~ sp + method, data = df, FUN= "mean" )
# by species and method
# sp method length
#1 1 A 4
#2 2 A 3
#3 1 B 6
#4 2 B 2
for everything together you may want:
aggregate(length ~ method, data = df, function(x) c(m = mean(x), counts = length(x)) )
# counts and mean for each method
# method length.m length.counts
#1 A 3.5 4.0
#2 B 4.0 4.0