4
$\begingroup$

I have two lists of equal length:

list1 = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}
list2 = {1, 1, 13, 66, 321, 1438, 6118, 24119, 86840, 279953, 799933, 1989738, 4248591, 7652030, 11438360, 14100690, 14420711, 12373780, 8857815, 5102917, 2264651, 752894, 181440, 30033, 2993, 116}

The elements of the first list represent the bin size component and the second list represents the count of a given size component. What I am trying to achieve is to convert these two lists into a list of lists that can be used as input into the Histogram function.

I'm sure this is embarrassingly simple Mathematica list manipulation stuff, but for the life of me, I can't seem to come up with an easy way to convert the data.

What I have thus far is something like this:

dataset1 = Table[2, {i, 1, 1}]
dataset2 = Table[3, {i, 1, 1}]
dataset3 = Table[4, {i, 1, 13}]
dataset4 = Table[5, {i, 1, 66}] 
dataset5 = Table[6, {i, 1, 321}]
...
dataset26 = Table[27, {i, 1, 116}]

The desired output would look something like this (using just the first handful and last elements from both lists:

{{dataset1},{dataset2},{dataset3},...{dataset26}}

Fleshed out:

{{2}, {3}, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, ... {27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27}}

Generally in pseudocode:

while index < Length[list1]
datasetn = Table[list1[[index]], {i, 1, list2[[index]]]
index++

This seems to be close:

(* b is the bin size, c is the count *)
f[b_, c_] := Table[b, {x, 1, c}];
Do[f[list1[[i]], list2[[i]]], {i, 1, Length[list1]}]

But, when I execute it, Mathematica is busy for a bit, and then I see no output. Plus, even if it did generate output, it would be just a bunch of lists, as opposed to a list of lists which is what I want.

I know that I could perform the task using plain-old procedural code in Mathematica, but a. From my limited experience with Mathematica in the past, my recollection is that it's typically more efficient or smarter to use more 'native' approaches such as Map. b. As I refamiliarize myself with Mathematica, I'd like to know how to do these types of things the Mathematica way.

The source of the lists is the output of a .NET program written to analyze graphs, and my end goal is to write the output generated by it into files which can then be ingested by Mathematica, but I'm obviously not there yet!

Thanks for taking a look!

(I edited it to show an example of the type of output I'm looking for along with a basic attempt at solving the problem with procedural code.)

$\endgroup$
6
  • 1
    $\begingroup$ Would BarChart[Transpose[{list1, list2}]] get you close to what you need? Histogram takes the raw data and calculates the frequencies. But you already have the frequencies, so you can plot them directly with BarChart. $\endgroup$
    – MarcoB
    Commented May 16 at 14:49
  • 1
    $\begingroup$ If you want a list of each number in list1 repeated list2 times, perhaps MapThread[ConstantArray, {list1, list2}]; is what you're looking for? You can then Flatten the list of lists to histogram the data (though it will be slow to histogram because the flatten list has ~85 million elements) $\endgroup$
    – ydd
    Commented May 16 at 14:50
  • $\begingroup$ @ydd I edited my comment to make my intention clear (list of lists). However, I can see that your proposal achieves the same thing I think, i.e., to the Histogram function, it is immaterial whether the data comes in as a list of lists or just as one big list. So, thank you for the idea and technique! $\endgroup$
    – anonmous
    Commented May 16 at 15:11
  • $\begingroup$ @MarcoB, that's awesome, thank you! I didn't know about BarChart. It gets me exactly where I need to be in terms of utility. However, just for general knowledge, I'm still trying to figure out how I could create a list of lists from the type of input I've indicated. $\endgroup$
    – anonmous
    Commented May 16 at 15:16
  • $\begingroup$ I'm still trying to figure out how I could create a list of lists from the type of input I've indicated. @ydd already showed you that. $\endgroup$
    – lericr
    Commented May 16 at 15:22

1 Answer 1

6
$\begingroup$

You might actually want WeightedData:

weighteddata = WeightedData[list1, list2]

Then you can just do:

Histogram[weighteddata, Length@list1]

I'm assuming that you want a number of bins equal to the length of the lists, but you can specify whatever bin spec you want.

$\endgroup$
4
  • $\begingroup$ WeightedData nice! I especially like that I can call all sorts of statistical functions on it. I tried the example Histogram code that you gave me, and I got a number of errors, starting with Rule:: Rule called with 1 argument; 2 arguments are expected. Maybe my version is too old (I'm running 11.3)? $\endgroup$
    – anonmous
    Commented May 16 at 15:21
  • $\begingroup$ WeightedData has been around since version 9. Try clearing your symbols or restarting the kernel. I don't know why you'd get a Rule-related message, because there are no explicit Rule expressions anywhere in what you provided or what I demonstrated. $\endgroup$
    – lericr
    Commented May 16 at 15:26
  • $\begingroup$ I restarted Mathematica and that did the trick! Thank you. (I tried to upvote your answer but don't have enough rep, sorry.) $\endgroup$
    – anonmous
    Commented May 16 at 15:36
  • $\begingroup$ Glad to help!!! $\endgroup$
    – lericr
    Commented May 16 at 16:03

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.