pivot_wider für Datensätze

Oct 03 2020

Ich möchte diesen Datensatz transformieren:

Dataset[{
  <|"Name" -> "Steven","Born" -> 1980, "Year" -> 2017, "Score" -> 115|>,
  <|"Name" -> "Steven", "Born" -> 1980, "Year" -> 2018, "Score" -> 230|>,
  <|"Name" -> "Joe", "Born" -> 1981, "Year" -> 2017, "Score" -> 70|>,
  <|"Name" -> "Joe", "Born" -> 1981, "Year" -> 2018, "Score" -> 300|>
}]

in diesen Datensatz:

Dataset[{
  <|"Name" -> "Steven", "Born" -> 1980, "Score_2017" -> 115, "Score_2018" -> 230|>,
  <|"Name" -> "Joe", "Born" -> 1981, "Score_2017" -> 70, "Score_2018" -> 300|>
}]

In Rs Tidyr wird diese Operation aufgerufen pivot_wider.

Irgendwelche Hinweise?

Ich weiß, dass es eine erfordert GroupBy["Name"]

Antworten

7 SjoerdSmit Oct 03 2020 at 22:27

Dies ist der einfachste Weg, den ich mir vorstellen kann:

ds = Dataset[{
  <|"Name" -> "Steven","Born" -> 1980, "Year" -> 2017, "Score" -> 115|>,
  <|"Name" -> "Steven", "Born" -> 1980, "Year" -> 2018, "Score" -> 230|>,
  <|"Name" -> "Joe", "Born" -> 1981, "Year" -> 2017, "Score" -> 70|>,
  <|"Name" -> "Joe", "Born" -> 1981, "Year" -> 2018, "Score" -> 300|>
}];
ds[
  GroupBy[#Name &],
  ResourceFunction["MergeByKey"][{{"Name", "Born"} -> First}]
][
  Values,
  Append[KeyDrop[#, {"Year", "Score"}],
    AssociationThread["Score_" <> ToString[#]& /@ #Year, #Score]
  ]&
]

Wenn verschiedene Personen unterschiedliche Jahre haben, möchten Sie möglicherweise KeyUnionden Datensatz wieder quadratisch machen. Dokumentation für MergeByKeyist hier

5 AntonAntonov Oct 04 2020 at 01:53

Sie können das Paket "DataReshape.m" wie unten gezeigt verwenden. (Es steht in meiner ToDo-Liste, die entsprechenden Funktionen sehr bald an das Wolfram Function Repository zu senden.)

Laden Sie das Paket:

Import["https://raw.githubusercontent.com/antononcube/MathematicaForPrediction/master/DataReshape.m"]

Hier ist der Originaldatensatz:

dsData = Dataset[{<|"Name" -> "Steven", "Born" -> 1980, 
     "Year" -> 2017, "Score" -> 115|>, <|"Name" -> "Steven", 
     "Born" -> 1980, "Year" -> 2018, "Score" -> 230|>, <|
     "Name" -> "Joe", "Born" -> 1981, "Year" -> 2017, 
     "Score" -> 70|>, <|"Name" -> "Joe", "Born" -> 1981, 
     "Year" -> 2018, "Score" -> 300|>}];
dsData

Konvertieren wir es in eine "richtige" Langform mit allen ID-Variablen außer "Score":

dsLong = ToLongForm[dsData, {"Name", "Born", "Year"}, Automatic]

Hier ändern wir die Werte der Spalte "Variable", um die Werte der Spalte "Jahr" als Suffixe zu erhalten:

dsLong2 = 
 dsLong[All, 
  Join[KeyTake[#, {"Name", "Born", "Value"}], <|
     "Variable" -> 
      StringRiffle[{#Variable, ToString[#Year]}, "_"]|>] &]

Hier konvertieren wir in eine breite Form mit den ID-Variablen "Name" und "Born":

ToWideForm[dsLong2, {"Name", "Born"}, "Variable", "Value"]

4 Stephan Oct 04 2020 at 06:09

Sowohl Sjoerds als auch Antons Antworten funktionieren gut. Nach der Lösung MergeByKeyvon Sjoerd aus dem Wolfram Function Repository wollte ich der Vollständigkeit halber hier posten, dass man fast die gleiche Lösung Mergeaus der Wolfram-Sprache finden kann:

ds = Dataset[{
  <|"Name" -> "Steven", "Born" -> 1980, "Year" -> 2017, "Score" -> 115|>,
  <|"Name" -> "Steven", "Born" -> 1980, "Year" -> 2018, "Score" -> 230|>,
  <|"Name" -> "Joe",    "Born" -> 1981, "Year" -> 2017, "Score" -> 70 |>,
  <|"Name" -> "Joe",    "Born" -> 1981, "Year" -> 2018, "Score" -> 300|>
}];
ds[GroupBy["Name"], Merge[#, Identity] &][Values,
  Append[Map[First, KeyDrop[#, {"Year", "Score"}]], 
    AssociationThread["Score_" <> ToString[#] & /@ #Year, #Score]] &]