I suggest that a counting hash be used to obtain the subtotals for the key :value and then construct the required of array of hashes from that hash. This uses the form of Hash#new that takes an argument that is the hash's default value. That means that if a hash h does not have a key k, h[k] returns the default value.
Computing totals
a.each_with_object(Hash.new(0)) {|g,h| h[[g[:subject_id], g[:element_id]]] += g[:value]}.
map {|(sub, el), tot| { subject_id: sub, element_id: el, value: tot}}
#=> [{:subject_id=>1, :element_id=>2, :value=>95},
# {:subject_id=>1, :element_id=>4, :value=>38},
# {:subject_id=>2, :element_id=>2, :value=>8},
# {:subject_id=>2, :element_id=>4, :value=>9}]
Ruby, as a first step, unpacks the expression
h[[g[:subject_id], g[:element_id]]] += g[:value]
changing it to
h[[g[:subject_id], g[:element_id]]] = h[[g[:subject_id], g[:element_id]]] + g[:value]
If h does not have a key [g[:subject_id], g[:element_id]], h[[g[:subject_id], g[:element_id]]] on the right side of the equality returns the default value, 0.
Note that
a.each_with_object(Hash.new(0)) {|g,h| h[[g[:subject_id], g[:element_id]]] += g[:value]}
#=> {[1, 2]=>95, [1, 4]=>38, [2, 2]=>8, [2, 4]=>9}
Computing averages
Only a small change is needed to compute averages.
a.each_with_object({}) do |g,h|
pair = [g[:element_id], g[:subject_id]]
h[pair] = {tot: 0, count: 0} unless h.key?(pair)
h[pair] = {tot: h[pair][:tot] + g[:value], count: h[pair][:count]+1}
end.map {|(sub, el),h| {subject_id: sub, element_id: el,
average: (h[:tot].to_f/h[:count]).round(1)}}
#=> [{:subject_id=>2, :element_id=>1, :average=>31.7},
# {:subject_id=>4, :element_id=>1, :average=>12.7},
# {:subject_id=>2, :element_id=>2, :average=>4.0},
# {:subject_id=>4, :element_id=>2, :average=>9.0}]
Note
a.each_with_object({}) do |g,h|
pair = [g[:element_id], g[:subject_id]]
h[pair] = {tot: 0, count: 0} unless h.key?(pair)
h[pair] = {tot: h[pair][:tot] + g[:value], count: h[pair][:count]+1}
end
#=> {[2, 1]=>{:tot=>95, :count=>3}, [4, 1]=>{:tot=>38, :count=>3},
# [2, 2]=>{:tot=> 8, :count=>2}, [4, 2]=>{:tot=> 9, :count=>1}}