2
$\begingroup$

I have multi-valued functions that create lists of data like the following:

dat={{1, {2.2`, 0.6`, 0.8`, 1.3`}}, {2, {4.2`, 1.1`, 1.8`, 
2.8`}}, {3, {6.2`, 1.6`, 2.8`, 4.3`}}, {4, {8.2`, 2.1`, 3.8`, 
5.8`}}, {5, {10.2`, 2.6`, 4.8`, 7.3`}}, {6, {12.2`, 3.1`, 5.8`, 
8.8`}}, {7, {14.2`, 3.6`, 6.8`, 10.3`}}, {8, {16.2`, 4.1`, 7.8`, 
11.8`}}, {9, {18.2`, 4.6`, 8.8`, 13.3`}}, {10, {20.2`, 5.1`, 9.8`, 
14.8`}}, {11, {16.3`, 10.8`, 5.6`, 21.8`, 18.9`}}, {12, {17.8`, 
11.8`, 6.1`, 23.8`, 20.599`}}, {13, {19.3`, 12.8`, 6.6`, 25.8`, 
22.299`}}, {14, {20.8`, 13.8`, 7.1`, 27.8`, 24.`}}, {15, {22.3`, 
14.8`, 7.6`, 29.8`, 25.7`}}}

The first element represents time. There are 3 or 4 or 5 values for each time. I need to make lists where each value is associated with a time so I can can plot them and interpolate them to make each value/time pair into a differentiable function. I have extracted one or two individual parts of the sublists, but cannot separate out all the pieces because the sublists are ragged; i.e., not all the same length. Can you help?

$\endgroup$

3 Answers 3

2
$\begingroup$

Are you looking for something like this?

dat = (* your data listed above *)
sorted = Flatten[
  Table[
    {dat[[i, 1]], dat[[i, 2, j]]}, 
    {i, Length[dat]}, 
    {j, Length[dat[[i, 2]]]}
  ],
  {2}
]

Table of sorted numbers.

Plot of sorted numbers.

I'm not sure if the plots are supposed to crossover or not. Your question doesn't specify exactly how to deal with the different lengths of lists, but it probably wouldn't be too difficult to change if this isn't exactly what you want.

EDIT 1

To address your comment about selecting a certain range of data, this is how I would do it:

selected = Select[#, 5 <= #[[1]] <= 10 &] & /@ sorted /. {} -> Nothing

The second argument to Select is 5 <= #[[1]] <= 10 &. This tells it to test the first number in each pair for whether it's between 5 and 10, inclusive. The # in the first argument pairs with the &/@sorted and tells it to perform the Select[] with each element of sorted. The final step /. {} -> Nothing tells it to drop any lists that end up empty.

The 5 and 10 can obviously be changed to whatever values you like.

$\endgroup$
2
  • $\begingroup$ This help. I now need to select the data from the lists that fall within a certain range. So I need all the data that fall between xmin[t] and xmax[t] Can I perform this selections out of the structures created from your answer? $\endgroup$ Nov 4, 2019 at 22:57
  • $\begingroup$ @Klandgren See my edit for one possible way to do the selection. $\endgroup$
    – MassDefect
    Nov 4, 2019 at 23:06
1
$\begingroup$

Using Flatten:

A ragged array, such as the one presented, can be transposed using Flatten.

dat2 = (Thread[First@# -> Last@#] & /@ dat // 
    Flatten[#, {{2}, {1}}] &) /. Rule :> List

{{{1, 2.2}, {2, 4.2}, {3, 6.2}, {4, 8.2}, {5, 10.2}, {6, 12.2}, {7, 14.2}, {8, 16.2}, {9, 18.2}, {10, 20.2}, {11, 16.3}, {12, 17.8}, {13, 19.3}, {14, 20.8}, {15, 22.3}}, {{1, 0.6}, {2, 1.1}, {3, 1.6}, {4, 2.1}, {5, 2.6}, {6, 3.1}, {7, 3.6}, {8, 4.1}, {9, 4.6}, {10, 5.1}, {11, 10.8}, {12, 11.8}, {13, 12.8}, {14, 13.8}, {15, 14.8}}, {{1, 0.8}, {2, 1.8}, {3, 2.8}, {4, 3.8}, {5, 4.8}, {6, 5.8}, {7, 6.8}, {8, 7.8}, {9, 8.8}, {10, 9.8}, {11, 5.6}, {12, 6.1}, {13, 6.6}, {14, 7.1}, {15, 7.6}}, {{1, 1.3}, {2, 2.8}, {3, 4.3}, {4, 5.8}, {5, 7.3}, {6, 8.8}, {7, 10.3}, {8, 11.8}, {9, 13.3}, {10, 14.8}, {11, 21.8}, {12, 23.8}, {13, 25.8}, {14, 27.8}, {15, 29.8}}, {{11, 18.9}, {12, 20.599}, {13, 22.299}, {14, 24.}, {15, 25.7}}}

ListLinePlot[dat2]

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ shorter alternative Flatten[Thread /@ dat, {2}] (+1) $\endgroup$
    – kglr
    Apr 21, 2023 at 4:53
1
$\begingroup$

We can construct a TemporalData object as follows:

td = TemporalData[PadRight[dat[[All, 2]], Automatic, Null], {dat[[All, 1]]}];


ListLinePlot @ td

enter image description here

Extract components using the property "PathComponent". For example:

td["PathComponent", 1]["Path"]

enter image description here

Use TimeSeriesWindow to get the portion corresponding to desired time range:

TimeSeriesWindow[td, {5, 11}]

enter image description here

ListLinePlot @ %

enter image description here

Use the property "SliceData" to get cross-sectional slices. For example,

td["SliceData", 14]
{{20.8,13.8,7.1,27.8,24.}}
$\endgroup$

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.