2
$\begingroup$

I want to add 19 lists together and then average over them but they are of unequal length. How do I make then all the same length? i.e. make them all the length of the smallest one.

My lists are called

nthrealisation[n_] := RESULTS[[{n}, All]];

For each n (ranging from 1-19) the lists are different lengths.

RESULTS = {};
For[iterator = 1, iterator < 20, iterator++,
 n = 200; m = 200; t = 0;
 results = {{t, n, m}};
 mu = 0.1; nimmig = 1;
 While[t < 1000,
  death = mu*2*n*m;
  birth = mu*(n + m);
  rate = death + birth + nimmig;
  deltaT[r_] := -1/r*Log[RandomReal[]];
  t1 = deltaT[rate];
  t = t + t1;
  rand = RandomReal[]*rate;
  rand1 = RandomReal[];
  rand2 = RandomReal[]*rate;
  rand3 = RandomReal[];
  Which[
   rand <= death,
   Which[
    rand1 <= (n/(n + m)), (n = n - 1) && (m = m),
    If[
     (rand2 > death) && (rand2 <=death + birth) && (rand3 < (m/(n + m))), (n= n) && (m = m + 1), (n = n) && (m = m)
     ];
    True, (n = n) && (m = m - 1)
       If[
        (rand2 > death) && (rand2 <=death + birth) && (rand3 < (n/(n + m))),(n = n + 1) && (m = m), (n = n) && (m = m)
        ];
    ];
   (rand > death) && (rand <= death + birth),
   Which[
    rand1 < (n/(n + m)), (n = n + 1) && (m = m),
    If[
     (rand2 < death) && (rand3 < (m/(n + m))), (n = n) && (m =m - 1), (n =n) && (m = m)
     ];
    True, (n = n) && (m = m + 1)
        If[
        (rand2 < death) && (rand3 < (n/(n + m))), (n = n - 1) && (m = m), (n= n) && (m = m)
        ];
    ];
   True,
   If[
     rand1 <= 1/2, (n = n + 1) && (m = m), (n = n) && (m = m + 1)
     ];
   ];
  results = Append[results, {t, n, m}];
  ];
 AppendTo[RESULTS, results];
 ]

 nthrealisation[n_] := RESULTS[[{n}, All]];
$\endgroup$
8
  • $\begingroup$ So if the length of the smallest list is 3, then you want entries 4, 5, ... in the other lists to be dropped? If so, try lists = Table[nthrealisation[n], {n, 19}]; With[{nmin = Min[Length /@ lists]}, Take[#, nmin] & /@ lists] $\endgroup$ Commented Mar 21, 2018 at 17:08
  • $\begingroup$ That doesn't seem to work. I added your code and evaluated. Then I did "Sum[nthrealisation[n],{n,19}]" to add up all the lists but it still says that they are of unequal length @J.M. $\endgroup$
    – Mlo27
    Commented Mar 21, 2018 at 17:25
  • $\begingroup$ Because I didn't sum the lists yet, and you still haven't answered my question. Use Total[] on the result of that last snippet, instead of Sum[]. $\endgroup$ Commented Mar 21, 2018 at 17:30
  • $\begingroup$ Yes, what you assumed is correct. However, I am still very confused as to what you mean. @J.M. $\endgroup$
    – Mlo27
    Commented Mar 21, 2018 at 17:36
  • $\begingroup$ When you evaluated my last snippet, you got output, yes? After getting that output, type Total[%] in a new cell and evaluate that. $\endgroup$ Commented Mar 21, 2018 at 17:49

2 Answers 2

2
$\begingroup$
lists = {{a, b, c}, {w, x, y, z}, {r, s, t, u, v}};

To make the elements of lists the same length you can use

Needs["GeneralUtilities`"]
TrimRight[lists]

{{a, b, c}, {w, x, y}, {r, s, t}}

You get the same result using

Take[#, Min[Length /@ lists]] & /@ lists (* as suggested by @JM in a comment *)
Take[lists, All, Min[Length /@ lists]]
PadRight[#, Min[Length /@ lists]] & /@ lists
lists[[All, ;; Min[Length /@ lists]]]

To get the mean, just use Mean on the trimmed list:

Mean[TrimRight[lists]]

{1/3 (a + r + w), 1/3 (b + s + x), 1/3 (c + t + y)}

Similarly for Total:

Total[TrimRight[lists]]

{a + r + w, b + s + x, c + t + y}

Update: working with OP's actual data:

lists = RESULTS;
Dimensions /@ lists

{{6384, 3}, {5962, 3}, {5867, 3}, {5972, 3}, {5960, 3}, {6088, 3}, {6186, 3}, {6227, 3}, {6161, 3}, {5866, 3}, {6171, 3}, {6191, 3}, {6269, 3}, {6099, 3}, {5987, 3}, {5848, 3}, {6064, 3}, {6156, 3}, {5923, 3}}

trimmedlists = lists[[All, ;; Min[Length /@ lists]]];
Dimensions /@ trimmedlists

{{5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}, {5848, 3}}

means = Mean[trimmedlists];
Dimensions@means

{5848, 3}

Note: The function nthrealisation[n] wraps the list of interest with {..}, e.g.,

Dimensions[nthrealisation[1]]

{1, 6384, 3}

So if you want to use the function nthrealisation to construct a list of lists, you need to use nthrealisation[n][[1]] when you are generating lists:

lists = Table[nthrealisation[n][[1]], {n, 19}]

Alternatively, define your function as

nthrealisation2[n_] := RESULTS[[n]]

and use

lists = Table[nthrealisation2[n], {n, 19}]
$\endgroup$
8
  • $\begingroup$ I have a very basic understanding of Mathematica, so am unsure of how to implement this into my coding $\endgroup$
    – Mlo27
    Commented Mar 21, 2018 at 17:29
  • $\begingroup$ @Mlo27, welcome to mma.se. You can replace lists with your RESULTS. $\endgroup$
    – kglr
    Commented Mar 21, 2018 at 17:35
  • $\begingroup$ Still doesn't seem to work. May I add that my lists "nthrealisation[n]" contains approx 6000 elements. $\endgroup$
    – Mlo27
    Commented Mar 21, 2018 at 17:42
  • $\begingroup$ I have attached my coding for you to see. @kglr $\endgroup$
    – Mlo27
    Commented Mar 21, 2018 at 18:03
  • $\begingroup$ @Mlo27, please see the update. $\endgroup$
    – kglr
    Commented Mar 21, 2018 at 19:40
0
$\begingroup$

It is unclear quite what the OP seeks, but it makes little sense to trim a list just to make it the length of the shortest list.

I suspect this is what is needed:

Mean /@ {{a,b,c}, {d,f,g,h},{j,k,l,m,n,o}}

(*

{1/3 (a + b + c), 1/4 (d + f + g + h), 1/6 (j + k + l + m + n + o)}

*)

$\endgroup$
1
  • $\begingroup$ I am simulating two coupled populations. Each set of results (I have 19) contain times that an event happens and the occupation in each population. Hence, results are in the form {t,n,m}. However I want to take an average of all the simulation. For example when the first event occurs, second and so on, and then what the occupation number are for these averaged times. $\endgroup$
    – Mlo27
    Commented Mar 21, 2018 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.