这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?因此,我的希望是这样的:
当你在分发平台中点击“全部匹配”时,你会得到很多匹配

但是,如果最佳拟合的 AICc 在正态分布的 5 以内,您不妨使用正态拟合。那么,是否有办法编写脚本,让其遍历已经运行过最佳拟合的一堆列,然后如果所选拟合在正态分布的 AICc 的 5 以内,则将其调整为正态拟合(假设它是非正态的)?如果能够有一个输入框来输入您愿意接受的 AICc 增量,那将是一个加分项。双重奖励是从选择选项中删除学生 t、柯西和 ExGaussian,因为您无法计算这些分布上的过程能力(这将是运行此清理脚本后要运行的下一步)。
我已尝试但无法使其工作,如能得到任何帮助我将非常感激!!
史蒂夫
自动化和脚本回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?
是否有办法编写脚本,遍历已经运行过最佳拟合的一堆列
分布平台是否仍然开放并且包含所有结果,或者结果存储在哪里?您是否需要保持比较分布开放,还是只要一个分布拟合就足够了?
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?嘿@jthi !
是的,平台仍将开放,所有最佳匹配比较仍将存在。我认为理想情况下比较框仍将存在,但如果这样更方便,我也可以只使用最佳匹配。
所以从这里开始

对于这种适合的情况,将选择正常,但是假设正常在列表的下方,则将选择 SHASH

这里将选择正常值,因为它在 Johnson Sb 的 AICc 值的 5 以内。

希望这对您有帮助,感谢您的关注!
史蒂夫
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?与此相关的两个困难之处在于:您无法使用 JSL 对表格框进行默认排序(据我所知,这会在很多平台上造成问题),而且这使得很难正确设置复选框(它们的顺序与您看到的其他值的顺序不同,很可能它们并不总是按顺序排列的,或者其他原因)
正因为如此,我不确定这是否在每种情况下都有效(我尝试过不使用 For,但顺序确实发生了太大变化)
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Cities.jmp");
dt << Distribution(
Continuous Distribution(Column(:"pop- m"n), Process Capability(0)),
Continuous Distribution(Column(:POP), Process Capability(0)),
Continuous Distribution(Column(:Max deg. F Jan), Process Capability(0)),
Continuous Distribution(Column(:OZONE), Process Capability(0)),
Continuous Distribution(Column(:CO), Process Capability(0)),
Continuous Distribution(Column(:SO2), Process Capability(0)),
Continuous Distribution(Column(:NO), Process Capability(0)),
Continuous Distribution(Column(:PM10), Process Capability(0)),
Continuous Distribution(Column(:Lead), Process Capability(0)),
Continuous Distribution(Column(:X), Process Capability(0)),
Continuous Distribution(Column(:Y), Process Capability(0)),
Fit All
);
// Script basically starts from here
Names Default To Here(1);
obs = Current Report() << XPath("//OutlineBox[@helpKey='Distrib']");
If(N Items(obs) > 0,
dist = obs[1] << Get Scriptable Object;
);
obs = Report(dist) << XPath("//OutlineBox[text()='Compare Distributions']");
For Each({ob}, obs,
tb = ob[TableBox(1)];
vals = tb << get;
// Order might be incorrect in these
dists = vals["Distribution"];
normal_idx = Contains(dists, "Normal");
normal_aic = vals["AICc"][normal_idx];
m_aic = Matrix(vals["AICc"]);
// This comparison might require some fixes
ifs = (ob << parent) << XPath("//IfBox");
Remove From(ifs, 1, 2); // might require more robust method
fit_titles = (ifs << child) << get title;
If(Min(m_aic) >= normal_aic - 20 & normal_idx > 1,
For(i = 1, i <= N Items(dists), i++,
tb[1] << Set All(0);
tb[1] << Set(i);
idx = Contains(ifs << get, 1);
If(fit_titles[idx] == "Fitted Normal Distribution",
break();
);
);
);
);
Write();
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?感谢脚本@jthi !
我尝试运行它并收到此错误

从日志中:
/*:
访问或评估“fit_titles[ /*###*/idx]”的下标范围,fit_titles[/*###*/idx]
位于 C:\Users\steve.hampton\OneDrive - Precision Castparts Corp\Documents\Script 3.jsl 的第 54 行
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?您必须开始添加调试打印并检查哪里出错了。您可能必须将循环从 N Items(dists) 更改为 N Items(fit_titles) 或类似的东西。
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?我尝试采用与 Jarmo 类似但不同的解决方案。不同之处在于我选择使用比较分布大纲框下的表格框中的复选框。我推断(正确),如果正态 AICc 在实际选择的分布的 5 范围内,那么在 JSL 中需要做的就是取消选择 JMP 选择的分布的复选框,并选中正态分布的复选框。如果在 JSL 中取消选择和选择,则直方图上会显示正确的分布。但是,似乎用于在 JSL 中操作复选框的正常消息不会返回或正确设置复选框......除非我不完全了解表格框中显示的复选框。
请参阅下文以了解我的发现
names default to here(1);
dt =
// Open Data Table: semiconductor capability.jmp
// → Data Table( "semiconductor capability" )
Open( "$SAMPLE_DATA/semiconductor capability.jmp" );
dist = dt << Distribution(
Continuous Distribution(
Column( :INM2 ),
Process Capability(0),
fit all(1)
)
);
// From the current report, find all of the Compare Distribution boxes
//dist =( current report() << xpath( "//OutlineBox[text()='Compare Distributions']" ));
// There is a bug in JMP where the check boxes return a standard order, not the order displayed
checkBoxOrder = {
"Normal",
"Cauchy",
"Student's t",
"Lognormal",
"Exponential",
"Gamma",
"Johnson Sb",
"SHASH",
"ExGaussian",
"Normal 2 Mixture",
"Normal 3 Mixture",
"Weibull"
};
distr = dist<<REPORT></REPORT>
<P>我希望有人能帮我指出我的逻辑或使用错误。如果没有人能提供这样的提示,我会把这个问题交给 JMP 支持。</P>回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?我的猜测是复选框实际上与表格框没有关联 -> 当您对表格框进行排序时,复选框无法正确排序。然后默认情况下,表格框已经以不同于“默认”的方式排序。因此,您最终会陷入非常奇怪的境地,因为您不知道哪个索引设置了哪个项目,因为它们没有对齐。这就是为什么我使用非常复杂的 For 循环并检查哪个分布的 Ifbox 已启用。
如果您使用“默认”顺序(您无法使用 JSL 设置,这会导致其他平台出现问题,例如流程筛选),您会得到以下结果

这些通常是“正确”的指标。
我还没有尝试过是否可以根据当前排序顺序(或者根据哪一列用于排序的知识)计算出哪个索引是哪个。
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?嘿@jthi ,
再次感谢您(和@txnelson )的尝试!我一直在研究代码,大多数时候它都运行得很好。由于问题似乎是比较分布对排序的行为方式,我认为如果我不关心所有分布是否仍然存在,那么应该可以这样做:运行分布平台并拟合所有分布,然后制作比较分布输出的组合数据表,在新表中删除不能用于过程能力的三个分布,然后对顶部拟合的 AICc 与正常拟合的分布进行比较,然后对每个变量取顶部拟合或正常拟合并删除所有其余部分(从而使该表成为分布属性表),然后使用管理限制平台将这些分布应用为主表上的列属性,最后重新启动分布平台。我希望这个周末试一试,看看它是否有效。
史蒂夫
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?这是我最初的想法,所以我问你是否想保留比较分布,所以我就这么做了。只要你能保持不同平台之间的名称相同,它应该可以正常工作。
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?好吧,我明白了!我确信这不是很有说服力,但我想把它抛出来,希望它能帮助到其他人。
第一步是选择数据表中想要拟合分布的列。
//rev 8-24-24
names default to here(1);
dt=current data table();
colnames=dt<<GET selected="" columns=""> expr(var1),
1
)
)
)
)));
dt1<< New Column( "Column 14 2",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula(
If( Is Missing( Col Maximum( :Column 13, :Y ) ) & :Column 10 == 2,
1
)
),
Set Selected
);
dt1 << New Column( "Column 14",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( Sum( :Column 12, :Column 13,:Column 14 2 ) ),
Set Selected
);
wait(0);
// Delete column formula: Column 10
dt1:Column 10 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 11 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 12 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 13 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 14 << Delete Formula;
//Delete non-Normal fits that are wihtin our criteria
// Delete selected rows
dt1 << Select Where( :Column 14 == 1 ) <<
Invert Row Selection << Delete Rows;
//Puts all the Y's and distributiosn into lists
col={};
dist={};
for each row(dt1,
insertinto(col,:Y);
insertinto(dist,:Distribution);
);
close(dt1, nosave);
//bring back up the distribution platform but only with the Y's that we could fit a distribution to
rpt=new window("Best Distribution",
obj=dt<<DISTRIBUTION></DISTRIBUTION></GET>Thanks for the inspiration <A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/14366" target="_blank">@jthi</A> and <A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/2687" target="_blank">@txnelson</A> (I used a bunch of your other posts to help me get here)
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?干得好。
我仔细阅读了你的脚本并做了一些修改。
- 我将创建第 10 列的语法更改为与第 11 列 - 第 14 列的语法相同。我建议您更改所使用的名称。当前名称“第 10 列等”是 JMP 在创建列时使用的名称,需要默认列名。因此,您要在其上运行脚本的数据表很有可能包含一个使用您所使用的名称之一的列。我的建议是将第 10 列等更改为 _第 10 列_ 等,以避免出现此问题。
- 我将您的“新列”代码从指定公式更改为使用“设置每个值”。它提供了相同的功能,但没有创建公式,您的代码最终必须删除该公式。
- 我删除了用于创建列表、col 和 Dist 的 For Each Row。这可以在单个语句中完成,从而无需循环遍历数据表
- 我还建议您在代码开头进行检查,以确定是否实际选择了列,如果没有,则显示一条消息告诉用户选择列并再次运行脚本。
请参阅下面我的更改
//rev 8-24-24
names default to here(1);
dt=current data table();
colnames=dt<<GET selected="" columns=""> expr(var1),
1
)
)
)
)));
dt1<< New Column( "Column 14 2",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Each Value( //Formula(
If( Is Missing( Col Maximum( :Column 13, :Y ) ) & :Column 10 == 2,
1
)
),
Set Selected
);
dt1 << New Column( "Column 14",
Numeric,
"Continuous",
Format( "Best", 12 ),
Set Each Value( //Formula(
Sum( :Column 12, :Column 13,:Column 14 2 ) ),
Set Selected
);
wait(0);
/*
// Delete column formula: Column 10
dt1:Column 10 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 11 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 12 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 13 << Delete Formula;
// Delete column formula: Column 11
dt1:Column 14 << Delete Formula;*/
//Delete non-Normal fits that are wihtin our criteria
// Delete selected rows
/*dt1 << Select Where( :Column 14 == 1 ) <<
Invert Row Selection << Delete Rows;*/
dt1 << delete rows( dt1 << get rows where( :Column 14 != 1) );
//Puts all the Y's and distributiosn into lists
/*col={};
dist={};
for each row(dt1,
insertinto(col,:Y);
insertinto(dist,:Distribution);
);*/
col = dt1:Y << get values;
dist = dt1:Distribution << get values;
close(dt1, nosave);
//bring back up the distribution platform but only with the Y's that we could fit a distribution to
rpt=new window("Best Distribution",
obj=dt<<DISTRIBUTION></DISTRIBUTION></GET>
<P> </P>
<P> </P>回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?谢谢@txnelson !
这些变化很棒,帮助我学到更多。非常感谢您的时间和帮助!
史蒂夫
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?
这是我根据您的脚本所采用的方法
Names Default To Here(1);
/*
dt = Open("$SAMPLE_DATA/Cities.jmp");
*/
NON_VALID_DIST = {"Cauchy", "ExGaussian", "Student's t"};
If(N Table() == 0,
Throw("No tables open");
);
dt = Current Data Table();
colnames = dt << Get selected Columns(continuous, "string");
If(N Items(colnames) == 0,
Throw("No continuous columns selected");
);
nw = New Window("What AICc is comparable?", Show Menu(0), Show Toolbars(0), <<MODAL> 1, // Normal isn't the only distribution
If(dt_fits[yrows[2], "AICc"] - same_limit <= dt_fits[yrows[1], "AICc"],
aa_y[ycol] = "Normal";
,
aa_y[ycol] = dt_fits[yrows[1], "Distribution"];
);
,
aa_y[ycol] = "Normal";
);
);
Close(dt_fits, No save);
dist = dt << Distribution(
Column(Eval(aa_y << get keys)),
Process Capability(0),
Invisible
);
For Each({{col, best_dist}, idx}, aa_y,
Eval(Substitute(
Expr(dist[idx] << _fit_),
Expr(_fit_), Parse("Fit " || best_dist); // I hate using Evil Parse, but in this case it might work as long as you "fix" Johnson fits
));
);
dist << Show Window(1);
Caption(Remove);
Write();</MODAL>
我还会考虑一次创建一列最佳拟合的第一个分布。这样,您可以在每一列之后更新标题,因为计算最佳拟合可能需要很长时间(也可以考虑更新进度条)。
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?谢谢@jthi ,这里也有很多好东西可以学习!感谢大家的帮助!
史蒂夫
回复:这可能是一个很大的要求,但是当正态分布非常接近最佳拟合分布时,有人可以帮助编写一个脚本来尝试选择正态分布吗?另外,你可以用 if-elseif 或 Match 替换多个 if 语句。我还没有测试过这些,但这些应该能给你一些启发。
对于像您这样的多个 if 语句,它将始终检查所有语句,但只有一个应该匹配。如果您使用 if-elseif,它将在找到第一个匹配项时停止( If() )
For(i = 1, i <= N Items(col), i++,
If(
dist[i] == "Normal", obj[i]<< Fit Normal,
dist[i] == "Exponential", obj[i]<< Fit Exponential,
dist[i] == "Gamma", obj[i]<< Fit Gamma,
dist[i] == "Johnson Su", obj[i]<< Fit Johnson,
dist[i] == "Lognormal", obj[i]<< Fit Lognormal,
dist[i] == "Normal 2 Mixture", obj[i]<<FIT normal="" 2="" mixture=""></FIT>
<P> </P>
<P> </P>
<P><A href="https://www.jmp.com/support/help/en/18.0/#page/jmp/match-function.shtml#ww246655" target="_blank" rel="noopener noreferrer">Match()</A>通常应该更容易阅读,如果我没记错的话,它也稍微快一些</P>
<P> </P>
<CODE class=" language-jsl">For(i = 1, i <= N Items(col), i++,
Match(dist[i],
"Normal", obj[i]<< Fit Normal,
"Exponential", obj[i]<< Fit Exponential,
"Gamma", obj[i]<< Fit Gamma,
"Johnson Su", obj[i]<< Fit Johnson,
"Lognormal", obj[i]<< Fit Lognormal,
"Normal 2 Mixture", obj[i]<<FIT normal="" 2="" mixture=""></FIT>
<P> </P>
<P> </P>