Group Abstract Group Abstract

Message Boards Message Boards

0
|
5.2K Views
|
6 Replies
|
3 Total Likes
View groups...
Share
Share this post:

Transpose each column of a data set with the first column?

Posted 5 years ago

I'm trying to Transpose each value list of association. This is actually a dataset problem, but I thought it would be easier to get answers here for associations. I go into more detail about the data set problem under the little break.

I currently have a list of associations which looks like this:

    assoc = 
{<|"a" -> 5, "b" -> 7, "c" -> 9, "d" -> 8|>,
 <|"a" -> 3, "b" -> 12, "c" -> 14, "d" -> 17|>,
 <|"a" -> 8, "b" -> 0, "c" -> 5, "d" -> 32|>}

And I want to Transpose each "b","c","d" with each "a": so my output would be:

{{"a" -> 5, "b" -> 7},
{"a" -> 5, "c" -> 9},
{"a" -> 5, "d" -> 8},
{"a" -> 3, "b" -> 12}, 
{"a" -> 3, "c" -> 1},
{"a" -> 3, "d" -> 17},
{"a" -> 8, "b" -> 0}, 
{"a" -> 8, "c" -> 5},
{"a" -> 8, "d" -> 32}}

I've tried various methods of mapping and transposing, but I can't find anything that actually works.

I'd love some help with this please!


If you're interested in the root of the problem - I have a data set which is built something like this:

ds={<|"date" -> "01/06", "a" -> 140., "b" -> 868., "c" -> 450., 
"d" -> 593., "e" -> 233., "f" -> 457.,
"g" -> 105.|>,

<|"date" -> "02/06", "a" -> 139., "b" -> 836., 
"c" -> 477., "d" -> 528., "e" -> 268., "f" -> 472., 
"g" -> 119.|>,

<|"date" -> "03/06", "a" -> 117., "b" -> 820., 
"c" -> 409., "d" -> 563., "e" -> 298., "f" -> 461.,
"g" -> 116.|>}

I'm trying to make a DateListPlot with all of the columns as lines, and "date" as the time series. The easiest way to make a DateListPlot seems to be to transpose each column with the date column (in my actual dataset the date column is all date objects):

DateListPlot[Transpose[{Normal[ds[All, "date"]] , Normal[ds[All, "a"]]}]]

But I can't figure out how to do this for each column and then put all the columns into the DateListPlot as separate lines.

POSTED BY: Rory Foulger
6 Replies
Posted 5 years ago

Hi Henrik,

Another possibility would be to view the values for each key across the timeline. e.g.

data0 = Rest /@ ds // Values // Transpose;
labels = ds // First // Rest // Keys;
DateListPlot[data0, {First@dates, Last@dates}, PlotLegends -> labels]

enter image description here

POSTED BY: Rohit Namjoshi

Hi Rohit, yes, the points are the same, but your graphics looks definitely better! I should have plotted al least no lines at all, just points ...

POSTED BY: Henrik Schachner

If you want to end up with a DateListPlot (as you wrote), you first have to generate DateObject(s). The rest is just some re-arranging.

dates = DateObject[{#["date"], {"Day", "/", "Month"}}] & /@ ds;
data0 = Rest /@ ds;
data1 = MapThread[Function[{date, value}, {date, #} & /@ value], {dates, data0}];
DateListPlot[data1, GridLines -> Automatic]

enter image description here

I do not know if this is what you want, but I cannot see any other application of DateListPlot here.

POSTED BY: Henrik Schachner
Posted 5 years ago

Hi Rory,

One way to do it (not particularly efficient)

distributeKey[key_][assoc_] := 
 KeyValueMap[<|KeyTake[assoc, key], <|#1 -> #2|>|> &, KeyDrop[assoc, key]]

distributeKey["a"] /@ assoc // Flatten

(* 
{<|"a" -> 5, "b" -> 7|>, <|"a" -> 5, "c" -> 9|>, <|"a" -> 5, 
  "d" -> 8|>, <|"a" -> 3, "b" -> 12|>, <|"a" -> 3, 
  "c" -> 14|>, <|"a" -> 3, "d" -> 17|>, <|"a" -> 8, 
  "b" -> 0|>, <|"a" -> 8, "c" -> 5|>, <|"a" -> 8, "d" -> 32|>}
*)

distributeKey["date"] /@ ds // Flatten

(*
{<|"date" -> "01/06", "a" -> 140.|>, <|"date" -> "01/06", "b" -> 868.|>, 
 <|"date" -> "01/06", "c" -> 450.|>, <|"date" -> "01/06", "d" -> 593.|>, 
 <|"date" -> "01/06", "e" -> 233.|>, <|"date" -> "01/06", "f" -> 457.|>, 
 <|"date" -> "01/06", "g" -> 105.|>, <|"date" -> "02/06", "a" -> 139.|>, 
 <|"date" -> "02/06", "b" -> 836.|>, <|"date" -> "02/06", "c" -> 477.|>, 
 <|"date" -> "02/06", "d" -> 528.|>, <|"date" -> "02/06", "e" -> 268.|>, 
 <|"date" -> "02/06", "f" -> 472.|>, <|"date" -> "02/06", "g" -> 119.|>, 
 <|"date" -> "03/06", "a" -> 117.|>, <|"date" -> "03/06", "b" -> 820.|>, 
 <|"date" -> "03/06", "c" -> 409.|>, <|"date" -> "03/06", "d" -> 563.|>,
 <|"date" -> "03/06", "e" -> 298.|>, <|"date" -> "03/06", "f" -> 461.|>, 
 <|"date" -> "03/06", "g" -> 116.|>}
*)
POSTED BY: Rohit Namjoshi

Or without Table

gg[xx_] := {xx[[1]], #} & /@ Drop[xx, 1]

gg /@ assoc1
% // Grid

or

Function[{x}, {x[[1]], #} & /@ Drop[x, 1]] /@ assoc1
POSTED BY: Hans Dolhaine

My system (Mathematica 7) does not understand your assoc. So I tried this

assoc1 = {{"a" -> 5, "b" -> 7, "c" -> 9, "d" -> 8},
  {"a" -> 3, "b" -> 12, "c" -> 14, "d" -> 17},
  {"a" -> 8, "b" -> 0, "c" -> 5, "d" -> 32}}

ff[x_] := Table[{First[x], x[[j]]}, {j, 2, Length[x]}]

ff[assoc1[[1]]]

ff /@ assoc1
% // Grid
POSTED BY: Hans Dolhaine
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard