Betreff: Stapeln in JSL-indizierten Spalten nach Gruppe (Sensordaten und Assets)Vielleicht so etwas:
Names Default To Here( 1 );
//dt=open("input_example.jmp");
//Stack data table
Data Table( "input_example.jmp" ) << Stack(
columns( Column Group( "A sensors" ), Column Group( "B sensors" ) ),
Source Label Column( "Label" ),
Stacked Data Column( "Data" ),
Output Table( "Stacked Data" )
);
//Text to columns
Data Table( "Stacked Data" ) << Text to Columns(
columns( :Label ),
Delimiters( " " )
);
//Delete column: Label 2
Data Table( "Stacked Data" ) << Delete Columns( :Label 2 );
//Change column name: Label 1 → Asset
Data Table( "Stacked Data" ):Label 1 << Set Name( "Asset" );
//Change column name: Label 3 → Sensor
Data Table( "Stacked Data" ):Label 3 << Set Name( "Sensor" );
//New column: Column 6
Data Table( "Stacked Data" ) << New Column( "Stddev of Sensor by Asset by Index",
Numeric,
"Continuous",
Format( "Best", 12 )
);
//Change column formula: Stddev of Sensor by Asset by Index
Data Table( "Stacked Data" ):Stddev of Sensor by Asset by Index <<
Set Formula( Col Std Dev( :Data, :Asset, :Index ) );
//Report snapshot: Stacked Data - Graph Builder
Data Table( "Stacked Data" ) << Graph Builder(
Size( 517, 450 ),
Show Control Panel( 0 ),
Variables(
X( :Index ),
Y( :Stddev of Sensor by Asset by Index ),
Overlay( :Asset )
),
Elements( Line( X, Y, Legend( 7 ) ), Points( X, Y, Legend( 8 ) ) )
);
Ich habe Worflow Builder in JMP 17 verwendet, um dieses Skript zu "schreiben".
Der Schlüssel liegt in der Verwendung der "by"-Argumente in der Formel.

Dadurch kann ich die Daten vollständig stapeln, um die vollständige Hierarchie mit den Daten in einer Spalte zu haben.
Dann erhalte ich die stddev der gesamten Datenspalte nach Asset und nach Index. Damit kann ich diese Grafik erstellen:

Betreff: Stapeln in JSL-indizierten Spalten nach Gruppe (Sensordaten und Assets)Das ist ein guter Ansatz. Bei einer vollständig gestapelten Tabelle besteht jedoch das Problem, dass sie auf die Formeln beschränkt ist, die ein „by“-Argument haben.
Wenn ich beispielsweise eine Formel erstellen möchte, die lautet: (Sensor 1 - Sensor 2) / Sensor 3, wird die By-Stacked-Tabelle benötigt.
Betreff: Stapeln in JSL-indizierten Spalten nach Gruppe (Sensordaten und Assets)Antwort entfernt, um zukünftige Leser nicht zu verwirren
Betreff: Stapeln in JSL-indizierten Spalten nach Gruppe (Sensordaten und Assets)Eine Option besteht darin, eine reine JSL-Route zu wählen, wenn Sie die Hierarchietabelle haben. Code könnte sich selbst erklären:
Names Default To Here(1);
dt_hier = Open("$DOWNLOADS/hierarchy_example.jmp");
dt_input = Open("$DOWNLOADS/input_example.jmp");
// some assumptions:
// both parents will have same amount of columns
new_col = dt_hier << New Column("Data Cols", Character, Nominal, << Set Each Value(
Regex(:Child column, "sensor \d")
));
data_cols = Associative Array(new_col) << get keys;
dt_hier << Delete Column(new_col);
dt_collector = New Table("data",
New Column("Index", Numeric, Ordinal),
New Column("Group", Character, Nominal)
);
For Each({data_col}, data_cols,
dt_collector << New Column(data_col, Numeric, Continuous)
);
Summarize(dt_hier, parents = by(:Parent));
For Each({parent}, parents,
parent_rows = Loc(dt_hier[0, "Parent"], parent);
parent_cols = dt_hier[parent_rows, "Child column"];
parent_data = dt_input[0, parent_cols];
non_missing_idx = Loc(parent_data);
row_count = N Items(non_missing_idx) / n cols(parent_data);
parent_data_clean = Shape(parent_data[non_missing_idx], row_count);
first_row = N Rows(dt_collector) + 1;
last_row = first_row + row_count - 1;
dt_collector << Add Rows(row_count);
dt_collector[Index(first_row, last_row), "Index"] = Index(1, row_count)`;
dt_collector[Index(first_row, last_row), "Group"] = Repeat({parent}, row_count);
dt_collector[Index(first_row, last_row), data_cols] = parent_data_clean
);

Hier werden einige Annahmen getroffen und keine ordnungsgemäße Fehlerbehandlung
Betreff: Stapeln in JSL-indizierten Spalten nach Gruppe (Sensordaten und Assets)Die Hierarchie kann bereits als Metadaten (Spalteneigenschaft) in der Tabelle vorhanden sein.
Ich habe das Beispiel aktualisiert, sodass Eltern (Gruppe), Eltern-Alias, Kind und Kind-Alias in die Tabelle eingebettet sind.
Ich denke, der intuitivste Ansatz besteht darin, die Tabelle nach einem Asset (Teilmenge) zu stapeln, Daten nach Label aufzuteilen und dann Tabellen miteinander zu verketten.
Betreff: Stapeln in JSL-indizierten Spalten nach Gruppe (Sensordaten und Assets)Ich habe auch die Anforderungen vereinfacht (keine leeren Werte mehr) und eine Lösung gefunden (Stack, Split, Concat), die iterativ (pro Asset) durchgeführt werden muss. Die Hierarchiedaten sind nun in der Haupttabelle eingebettet (Fortschritte sind im input_example zu finden).
Betreff: Stapeln in JSL-indizierten Spalten nach Gruppe (Sensordaten und Assets)Die einfachste Operation, die ich gefunden habe, war die Automatisierung dieser Datenschritte.
1) Stapel

2) Teilen

3) Verketten

Stapeln in JSL-indizierten Spalten nach Gruppe (Sensordaten und Assets)In der Fertigung ist es üblich, Sensordaten in der folgenden Form zu extrahieren: A und B entsprechen ähnlichen Geräten (bekannt als Vermögenswerte ).
In diesem Format muss der Benutzer eine kombinierte Formel für jede übergeordnete Gruppe erstellen. Zum Beispiel:
(Eingabe: Sensordatentabelle benötigt spezifische Spalten pro übergeordneter Gruppe)

Bei der Handhabung mehrerer Assets wird dies umständlich. Eine bessere Möglichkeit besteht daher darin, die Daten pro Gruppen-Asset zu stapeln.
Um dies programmgesteuert zu tun, benötigen wir Kontextdaten, die die Hierarchie enthalten. Zum Beispiel:
(Eingabe: Asset-Hierarchie)

Wie können Sie in JSL von den Sensordaten und der Hierarchie (Eingaben) zur Asset-Tabelle (gewünschte Ausgabe) wechseln?
(Ausgabe: Asset-Datentabelle)

Alle Tabellen und Skripte sind beigefügt. Hier ist das Eingabetabellenskript (Metadaten, die übergeordnete/untergeordnete Elemente enthalten, werden als Spalteneigenschaften hinzugefügt).
Names Default To Here( 1 );
// New data table
dt = New Table( "sensor table" );
n_rows = 10;
n_additional_rows = 0;
// New column: Index
dt << New Column( "Index", Numeric, "Continuous", Format( "Best", 12 ) ) <<
Begin Data Update << Add Rows( n_rows );
dt:Index << Set Formula( Row() );
dt << End Data Update;
// A sensor
dt << New Column( "A sensor 1",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Selected
) << New Column( "A sensor 2",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Selected
) << New Column( "A sensor 3",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Selected
) << Group Columns( "A sensors", {:A sensor 1, :A sensor 2, :A sensor 3} )
<< Begin Data Update;
For Each Row(
dt,
:A sensor 1 = Random Normal( 0, 1 );
:A sensor 2 = Random Normal( 0, 1 );
:A sensor 3 = Random Normal( 0, 1 );
);
dt << End Data Update;
// B sensors
dt << Add Rows( n_additional_rows );
dt << New Column( "B sensor 1",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Selected
) << New Column( "B sensor 2",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Selected
/*) << New Column( "B sensor 3",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Selected*/
) << Group Columns( "B sensors", {:B sensor 1, :B sensor 2}) //, :B sensor 3} )
<< Begin Data Update;
For Each Row(
dt,
:B sensor 1 = Random Normal( 0, 3 );
:B sensor 2 = Random Normal( 0, 2 );
//:B sensor 3 = Random Normal( 0, 3.5 );
);
dt << End Data Update;
colnames = dt << Get Column Names( String );
for each({col, index}, colnames,
column(dt, col) << Set Property( "child", col ) );
// Calculations.
// New formula column: Stdev[A sensor ...r 2,A sensor 3]
dt << New Column( "Stdev[A sensors]",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Std Dev( :A sensor 1, :A sensor 2, :A sensor 3 ) ));
// Move selected column: Stdev[A sensors]
dt <<MOVE selected="" columns=""></MOVE>
Automatisierung und Skripterstellung