使用自定义过滤应用程序过滤数据表大家好,
我正在构建一个包含大量报告的应用程序/仪表板。最后,我想让用户选择对主数据表进行“查询”,并在以后需要时保存它。
目前,我有一个按钮,它可以打开另一个窗口并提示用户选择过滤列(从预选列表中)。
一旦他们选择了它们,他们就会按下另一个按钮,然后该按钮将为每个过滤列创建一个列表框,其中包含所有可用的不同值。我的想法是,从这里开始,用户将在每个列表框中选择他们想要进行过滤的值,然后按下最后一个按钮来保存这些值,然后会构建一个过滤器/where 子句,它将对主数据表进行子集化并将其保存在已知位置。
我相信我已经成功了一半。我让第一个窗口和筛选列选择工作。然后我可以在列表框中显示值,但无法创建正确的按钮来保存这些选定的值。此外,我相信我遇到了不知道用户将创建多少个筛选列的问题,因此我必须有一个表达式来定义未知数量的列。我看到了一些带有 Eval(Parse(Eval Into 语句的示例,但还没有得到它。
任何帮助都将不胜感激。也许有更简化的方法可以做到这一点。
以下是我目前掌握的一些代码
filter_col_append_expr = Expr(
lub1 << Append(List Box(column(dt1,Char(col_filter[count_i])) <<GETASMATRIX></GETASMATRIX>
//The button which will run the whole thing is here. Some code is ommited
Panel Box("Database Query", Button Box("Query",query_expr;query_window << Append(bb3 = Button Box("Select Filter Values",query_values = lub1<<GET selected=""></GET><BR /><LINGO-LABS id="lingo-labs-828278" slang="en-US" mode="CREATE"><LINGO-LABEL>自动化和脚本</LINGO-LABEL><LINGO-LABEL>数据探索与可视化</LINGO-LABEL><LINGO-LABEL>视窗</LINGO-LABEL></LINGO-LABS>回复:使用自定义过滤应用程序过滤数据表您是否考虑过根据用户选择的列构建数据过滤器?
回复:使用自定义过滤应用程序过滤数据表是的,但是混乱程度越少越好,因为很多用户都是 JMP 新手,我想让他们尽可能轻松地进行可视化,只需按一下按钮即可获得过滤后的数据。
使用本地过滤器也可以
回复:使用自定义过滤应用程序过滤数据表我会构建数据过滤器(如果需要,您可以清理它),但这里有一个使用列表框的选项
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
options = dt << Get Column Names("String");
filter_col_append_expr = Expr(
Summarize(dt, colvals = By(Eval(selection))); // Note that Summarize this will change numeric values to strings
lub1 << Append(List Box(colvals));
);
query_expr = Expr(
query_window = New Window("Database Query",
Spacer Box(size(1, 5)),
vlb3 = V List Box(
Text Box("Select All Filter Columns"),
H List Box(
Spacer Box(size(1, 5)),
lb3 = List Box(
options,
max selected(8)
)
),
Spacer Box(size(1, 10)),
Button Box("Select Filter Columns",
cols = lb3 << get selected;
Try(lub1 << Delete Box());
lub_collector << Append(lub1 = Lineup Box(N Col(4)));
For Each({selection}, cols,
filter_col_append_expr
);
),
lub_collector = V List Box();
)
)
);
//The button which will run the whole thing is here. Some code is ommited
nw = New Window("",
Panel Box("Database Query",
Button Box("Query",
query_expr;
query_window << Append(
bb3 = Button Box("Select Filter Values",
vals = (lub1 << XPath("//ListBoxBox")) << get selected;
user_selections = Associative Array(cols, vals);
show(user_selections);
)
);
)
)
);
回复:使用自定义过滤应用程序过滤数据表谢谢,正如我所期望的那样。
可是,下一步我就有点走投无路了。
为了构建数据过滤器,我考虑直接将关联数组与用户选择放在一起,但这样做不行。
然后,我考虑将其分解为数据过滤器,并使用 Expr 和其他字符串命令来构建它,使其看起来与我构建交互式数据过滤器后使用红色三角形完全一样,但我认为我在语法上的某个地方出了问题。
这是我根据你的 BigClass 示例编写的代码
where_clause_list = {};
where_clause = "";
keys = user_selections << getkeys;
values = user_selections << getvalues;
For ( i=1, i<=NItems(keys), i++,
// Inner loop iterating over items for each category
For Each( {value}, values[i],
// Action for each category-item pair
(where_clause = where_clause || ":"||keys[i] || " ==" || " " || Char(value) || " &"|| " ");
InsertInto(where_clause_list, where_clause);
where_clause = "";));
where_clause="";
For Each({where},where_clause_list,where_clause=where_clause||where);
where_clause = Left(where_clause,Length(where_clause) -3);
Show(where_clause_list);
Show(where_clause);
where_expr = Expr(where_clause);
key_clause="";
For Each({key},keys,key_clause=key_clause||"Ascolumn("||key||")"||" ,");
key_clause = Left(key_clause,Length(key_clause) -2);
keys_expr=Expr(key_clause);
Show(key_clause);
dt << Data Filter(Add Filter(columns(key_expr),Where(where_expr),
Mode( Select( 0 ), Show( 1 ), Include( 1 ))));
然而,有没有更直接、更直观的方法来做到这一点?
回复:使用自定义过滤应用程序过滤数据表如果关联数组中已有选择,是否还需要数据过滤器?我之前建议使用数据过滤器,以避免创建“额外”列表框来选择行值。
回复:使用自定义过滤应用程序过滤数据表一旦我有了选择(列名和值),我想对数据进行子集化并仅提取用户选择过滤的内容。为此,我需要一些数据过滤器,对吗?
回复:使用自定义过滤应用程序过滤数据表根据您所说的“提取”的含义,您可以使用 << Get Rows Where + Subset 或 << Select Where + Subset 或 << Select Where + Hide and Exclude
回复:使用自定义过滤应用程序过滤数据表是的,我确实想使用其中的一些方法,但当我不知道用户选择了哪一列和哪一值时,我不确定该怎么做。选择现在在关联数组中,但将它们转换为 Where 子句对我来说很困难。这就是为什么我尝试用我之前展示的代码块来构造 Where 子句,但我没有成功。也许有一种更直接的方法可以使用关联数组来构造 where 子句
回复:使用自定义过滤应用程序过滤数据表直接使用数据过滤器是最简单的选择,但我们已经排除了这种选择。用户选择应该通过 AND 还是 OR 组合?
回复:使用自定义过滤应用程序过滤数据表以下是一些选项
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
// Build using Select Where (simplest)
// Note that we convert to Char due to using Summary and because we can have numeric values
// This could (and should) be handled earlier in some other method
user_selections = ["age" => {"13", "14"}, "sex" => {"F"}];
For Each({{col, values}, idx}, user_selections,
If(idx == 1,
dt << Select Where(Contains(values, Char(Column(dt, col)[])));
);
dt << Select Where(Contains(values, Char(Column(dt, col)[])), Current Selection("restrict")); // AND
// dt << Select Where(Contains(values, Char(Column(dt, col)[])), Current Selection("extend")); // OR
);
show(dt << get selected rows);
wait(1); // demo purposes
dt << Clear Select;
// A bit more complicated is to build expression and use that
user_selections = ["age" => {13, 14}, "sex" => {"F"}]; // simplified to use numeric value for numeric column
filter_expr = Expr(And()); // optionally use Or()
For Each({{col, values}, idx}, user_selections,
cur_expr = Substitute(
Expr(Contains(_list_, _column_)),
Expr(_list_), values,
Expr(_column_), Name Expr(AsColumn(dt, col))
);
Insert Into(filter_expr, Name Expr(cur_expr));
);
// Show(Name Expr(filter_expr));
my_rows = dt << Get Rows Where(filter_expr);
show(my_rows);