5

I have some data this

dataABC = {
   {"a", 1, 2, 3},
   {"b", 1, 3, 5},
   {"c", 1, 2, 1},
   {"a", 1, 2, 3},
   {"a", 1, 1, 1},
   {"c", 1, 1, 1},
   {"b", 2, 2, 2}
   };

As you can see," a "," b" and "c" are followed by a series of numbers that represent their values.

For example,if {"a",1,2,3}

enter image description here

There are a lot of sublists like {"a",1,2,3} in the above data.

So what I want to do now is take the average of a, b, c with respect to value1, value2, value3,My English is not very good, and the following picture can better illustrate what I mean.

enter image description here

To find their average,I'm going to sort the data so that the "a", the "b", the "c" are all together,like this

dataABC1 = dataABC // Sort

enter image description here

Now what I'm going to do is I'm going to average them, and I don't know how to do that, right,I have tried using functions such as Select, Cases, etc. without success. What should I do?

Syed
  • 52,495
  • 4
  • 30
  • 85
我心永恒
  • 1,488
  • 6
  • 9

3 Answers3

8
GroupBy[dataABC, First -> Rest, Mean]

<|"a" -> {1, 5/3, 7/3}, "b" -> {3/2, 5/2, 7/2}, "c" -> {1, 3/2, 1}|>

Further, if required:

FlattenAt[#, -1] & /@ (List @@@ 
   Normal@GroupBy[dataABC, First -> Rest, Mean])

{{"a", 1, 5/3, 7/3}, {"b", 3/2, 5/2, 7/2}, {"c", 1, 3/2, 1}}


More directly: (Mean of strings is a horrible idea but it works)

ArrayReduce[Mean, #, 1] & /@ GatherBy[dataABC, First]
Syed
  • 52,495
  • 4
  • 30
  • 85
6

A hand-writing way.

ans = <| |>;
cnt = <| |>;
dataABC = {
   {"a", 1, 2, 3},
   {"b", 1, 3, 5},
   {"c", 1, 2, 1},
   {"a", 1, 2, 3},
   {"a", 1, 1, 1},
   {"c", 1, 1, 1},
   {"b", 2, 2, 2}
   };
Table[
   head = First @ i;
   tail = Rest @ i;
   ans[head] = (ans[head]/._Missing -> {0,0,0}) + tail;(*https://mathematica.stackexchange.com/a/224165*)
   cnt[head] = (cnt[head]/._Missing -> 0) + 1,
   {i, dataABC}
];
ans // KeyValueMap[#1 -> #2 / cnt[#1]&]

{"a" -> {1, 5/3, 7/3}, "b" -> {3/2, 5/2, 7/2}, "c" -> {1, 3/2, 1}}

AsukaMinato
  • 9,758
  • 1
  • 14
  • 40
5
Reap[MapApply[Sow[{##2},#1]&]@dataABC,_, Flatten[{#,Mean@#2}]&][[2]]


(*
              5  7       3  5  7          3
      {{a, 1, -, -}, {b, -, -, -}, {c, 1, -, 1}}
              3  3       2  2  2          2

*)
user1066
  • 17,923
  • 3
  • 31
  • 49