你好,
我有一个大型数据表,其中的列有一个 ID 号,后面跟着下面的单词,
| 1-日期 | 1 参数 | 1东西 | 2东西 | 2-日期 | 2参数 | 3参数 | 3-日期 | 3东西 | 3-否则 |
| | | | | | | | | | |
| | | | | | | | | | |
我的最终目标是自动化以日期为样本标签的控制图。 每个 ID 的列数不统一,也不按日期升序排列。
我的想法是按 ID 将大型数据表拆分为较小的数据表,然后从中制作控制图。 但是,我不知道如何以自动方式进行这种拆分。
谢谢
如果您的表格没有规则的列模式,Jim 的解决方案是我提到的更通用的解决方案。 我点击 Post 后,Jum 的回复才出现。
查尔斯,
如果您的列有常规系列 3(日期、参数名称、数据值),这可以通过 UI 使用 Main Menu > Tables > Stack 并选择多系列堆栈 3 并逐行取消选中堆栈来完成。它需要对列名进行一些清理,但结果表可用于使用参数名称或数据组作为 By 变量的控制图。
或者,如果您想要单独的表,您可以在这个新表上使用表子集,选中子集依据,然后指定数据组。
如果您的表没有重复的系列顺序,则需要一个脚本或大量手动工作来对每个组进行子集化。 如果您的数据表的列顺序不规则,请回复此帖子。
我附加了一个 JSL 脚本,如果它具有重复的系列列并且所有日期和所有东西都是相同的建模类型(可能是数字的、连续的),它应该适用于您的表。
Names Default To Here(1);
dt = current data table();
cnames = dt << get column names("String");
stk = dt << Stack(
columns(
evalList(cnames)
),
Source Label Column( "Label" ),
Stacked Data Column( "Data" ),
Stack By Row( 0 ),
Number of Series( 3 )
);
stk:Data << Set Name("Date");
stk:Data 2 << Set Name("Parameter Name");
stk:Data 3 << Set Name("Data");
stk:Label << set each value( trim(word(1,:Label,"-")));
stk:Label << Set Name( "Data Group");
stk << delete columns(:Label 2, Label 3);
没有更多的细节,我只能给出一个大致的方向来解决这个问题。我看到有两种方法可以满足您的需求。首先是找出有多少个不同的 ID,并将列放入 ID 的不同列表中,执行以下操作:
Names Default To Here( 1 );
dt = Current Data Table();
colNamesList = dt << get column names( string );
// Create an ID list
listOfIDs = {};
For( i = 1, i <= N Items( colNamesList ), i++,
If( Contains( listOfIDs, Word( 1, Column( dt, colNamesList[i] ) << get name, "-" ) ) == 0,
// Insert into the listOfIDs, the new ID name
Insert Into( listOfIDs, Word( 1, Column( dt, colNamesList[i] ) << get name, "-" ) );
// Create a list to hold the column names for the new ID
Eval( Parse( "listOfColumns_" || Char( N Items( listOfIDs ) ) || " = {};" ) );
Eval(
Parse(
"insert into(listOfColumns_" || Char( N Items( listOfIDs ) ) || "," || Char(
Column( dt, colNamesList[i] ) << get name
) || ");"
)
);
,
// If the ID has already been see, then just add the column name to the
// ID list of column names
Eval(
Parse(
"insert into(listOfColumns_" || Char(
Contains( listOfIDs, Word( 1, Column( dt, colNamesList[i] ) << get name, "-" ) )
) || "," || Char( Column( dt, colNamesList[i] ) ) << get name || ");"
)
)
)
);
然后,您可以遍历 listOfIDs 并进行处理。
另一种方法是堆叠所有列,然后为 ID 创建一个新列,从标签中去除 ID 值,然后将列拆分回公共列并使用 By 语句进行处理以分隔不同的身份证。就像是
Names Default To Here( 1 );
dt = Current Data Table();
colNamesList = dt << get column names( string );
// Stack the columns
dtStack = dt << Stack(
columns( colNamesList ),
Source Label Column( "Label" ),
Stacked Data Column( "Data" ),
Drop All Other Columns( 1 )
);
// Create the ID Column
dtStack << New Column("ID", character,formula( word(1,:label,"-")));
// Now delete the ID from the :Label column
For Each Row(
:Label = trim(substr( :Label, contains(:Label,"-")+1));
);
// Split back to common columns
dtFinal = dtStack << Split(
Split By( :Label ),
Split( :Data ),
Sort by Column Property
);
现在让我澄清一下.......正如我所说,由于你的细节很少,我对此做了很多猜测。此外,如果没有示例数据表,我提供的代码还没有经过测试,我认为它不会在第一次执行时工作。它旨在显示您可以采取的解决问题的可能方向