线路差异假设我有两条线,分别是两个不同移动物体的距离与时间。对象 1 和对象 2 的时间测量是在任意时间进行的,即对象 1 的测量时间与对象 2 的测量时间不同。
图形生成器中有没有办法绘制这些曲线与时间之间的“差异”?
高级统计建模大规模定制质量和工艺工程回复:线路差异作为不同建议的组合,您还可以使用简单的 interpolate() - interpolate() 来计算差异,然后使用平滑图的 lambda 设置来调整曲线的粒度。

Open( "$DOWNLOADS/ab.jmp" );
New Column( "diff",
Formula(
rowsA = As Constant( Current Data Table() << get rows where( :Source Table == "a" ) );
rowsB = As Constant( Current Data Table() << get rows where( :Source Table == "b" ) );
xA = As Constant( :time[rowsA] );
xB = As Constant( :time[rowsB] );
posA = As Constant( :position[rowsA] );
posB = As Constant( :position[rowsB] );
If( Min( xA ) <= :time <= Max( xA ) & Min( xB ) <= :time <= Max( xB ),
Interpolate( :time, xA, posA ) - Interpolate( :time, xB, posB ),
.
);
)
);
Graph Builder(
Variables( X( :time ), Y( :diff ), Y( :position ), Overlay( :Source Table ) ),
Elements( Position( 1, 1 ), Points( X, Y, Overlay( 0 ), Legend( 1 ) ), Smoother( X, Y, Overlay( 0 ), Lambda( 0.02 ) ) ),
Elements( Position( 1, 2 ), Points( X, Y ), Smoother( X, Y ) )
);
回复:线路差异由于一些奇怪的许可问题*我今天才终于能够尝试这个。 它工作得很好,非常优雅!
两个问题:
- JSL 是否强大到足以为我改变这个公式? 那么整个过程可以编写成 .jsl 脚本吗?
- 当我更改平滑器上的 lambda 时,我预计差异曲线会更新,但事实并非如此。 更深入地观察,我发现“保存公式”实际上是保存样条线参数,而不是保持与所使用的实际样条线的连接。 我认为后者不太可能?
再次感谢!
******************************************
* 我最终被迫将 Mac 更新到 11.6,却没有意识到 JMP v14 无法在其上运行。 因此,我通过我的公司请求了 v16,在获得 PO 后实际上花了几个月的时间才为我真正获得 v16 许可证。 在税务证明、地址变更和采购订单问题等方面进行了大量的来回讨论。 我无法判断问题出在我公司的供应链还是 JMP/SAS 的销售部门,但如果你手头有钱,获得许可证确实应该不那么难。
回复:线路差异这是一个低脚本替代方案,使用保存公式红色小三角菜单中的命令可用于平滑器或拟合线元素。

从 Craige 的 ab.jmp 表开始,使用 Overlay 获取两条线/曲线,使用 Save Formula 获取一个新列,其中的公式如下所示:
If( :源表 == "a", 样条线 Eval( ... ), :源表 == "b", 样条线 Eval( ... ), . ))
进入新列的公式编辑器并更改公式以减去两个样条表达式:
样条线评估( ... ) - 样条线评估( ... )
并将其用作 GB 中的 Y。

回复:线路差异是的,退休了,我从回答问题中学到了很多东西。
@XanGregg对于图形生成器的建议。
回复:线路差异哇,令人印象深刻的解决方案! 并且有很好的记录,谢谢!!
唯一更好的办法是,如果 JMP 自己完成此操作,无需中间脚本步骤,但除了按住 Shift 键单击图形生成器中的两条线并要求一条差异线(这在概念上从心智模型来看是混乱的)之外,从它正在做什么的角度来看),我真的无法想象那会如何运作。
谢谢,克雷格!
(ps.你真的退休了吗? 提供 JMP 支持是为了好玩吗?)
回复:线路差异我认为你想要的是所谓的分段线性插值。 我不确定哪个平台可能会为此生成公式,但您可以执行类似的操作。 如果您使用这个,请自行测试!
dt = Open( "$desktop/ab.jmp" ); // table with unaligned times for a and b measurements
dt << sort( by( time ), replacetable( 1 ) ); // make sure time is ascending
aRows = dt << getrowswhere( SourceTable == "a" ); // get all the a
bRows = dt << getrowswhere( SourceTable == "b" ); // and b row indexes
aTimes = dt:time[aRows]; // get all the a and b times and positions in
aPositions = dt:position[aRows]; // matrices for the interpolate function
bTimes = dt:time[bRows];
bPositions = dt:position[bRows];
apos = Function( {time}, // tiny wrappers for interpolate
Interpolate( time, aTimes, aPositions )
);
bpos = Function( {time},
Interpolate( time, bTimes, bPositions )
);
dtnew = New Table( "new_ab", // new table is similar to old table
New Column( "Source Table", Character( 1 ), "Nominal" ),
New Column( "time", Numeric, "Continuous", Format( "Best", 12 ) ),
New Column( "position", Numeric, "Continuous", Format( "Best", 12 ) )
);
bigdif = 0; // track the largest difference so it can have a ref line
bigtime = .;
// make a new table covering the range of the data
For( i = min(min(aTimes),min(bTimes))-10, i <= max(max(aTimes),max(bTimes))+10, i += 1,
dtnew << addrows( 1 ); // interpolate a at time i
dtnew:SourceTable = "a";
dtnew:time = i;
dtnew:position = apos( i );
dtnew << addrows( 1 ); // interpolate b at time i
dtnew:SourceTable = "b";
dtnew:time = i;
dtnew:position = bpos( i );
dtnew << addrows( 1 ); // difference at time i
dtnew:SourceTable = "diff";
dtnew:time = i;
dtnew:position = apos( i ) - bpos( i );
If( Abs( dtnew:position ) > bigdif, // capture biggest diff
bigdif = Abs( dtnew:position );
bigtime = i;
);
);
dtnew << Graph Builder(
Size( 518, 448 ),
Show Control Panel( 0 ),
Variables( X( :time ), Y( :position ), Overlay( :Source Table ) ),
Elements( Points( X, Y, Legend( 21 ) ), Smoother( X, Y, Legend( 22 ), Lambda( 0.000001 ) ) ),
SendToReport(
Dispatch( {}, "time", ScaleBox, {Add Ref Line( bigtime, "Solid", "Black", "big=" || Char( bigtime ), 1 )} ),
Dispatch( {}, "Graph Builder", FrameBox, {Marker Size( 2 )} )
)
);像这样输入数据

像这样的插值数据

生成这样的图表:
The green curve is blue - red; the ref line is at the first biggest difference.The green curve is blue - red; the ref line is at the first biggest difference.绿色曲线为蓝-红;参考线位于第一个最大差异处。
如果这是一场比赛,a用71秒获胜,b用99秒输掉。 a 以 43 秒领先(好吧,也许吧。 您不能太确定 b 在原始数据中时间 43 的位置。)
您无法通过原始数据的简单线性拟合得到这一点:
Original data with linear fit.Original data with linear fit.线性拟合的原始数据。
回复:线路差异@马克贝利如果两条线是线性的,则 2 个性别组的按体重预测的身高拟合模型最终的项估计值为 -2.079223。当简化为线性回归时,这不是两条线之间的差异吗?

回复:线路差异
@马克贝利写道:
确切地。 曲线或形状的复杂性将决定所需模型的复杂性。 您能显示数据图的图片吗? 也许这些数据有一个理论模型?
我们无法为您提供进一步帮助,因为下一步是建模,但我们必须知道哪个模型才能为您提供帮助。
@马克贝利, @Craige_Hales -- 是的,点之间的线性拟合就可以了。 我意识到由于线性插值,差异会有些弹性,但这很好,我们只是看粗略的幅度。
回复:线路差异确切地。 曲线或形状的复杂性将决定所需模型的复杂性。 您能显示数据图的图片吗? 也许这些数据有一个理论模型?
我们无法为您提供进一步帮助,因为下一步是建模,但我们必须知道哪个模型才能为您提供帮助。
回复:线路差异如果您有一对数据表,每个对象一个,其中包含时间和距离列,您可以保存预测时间之间位置的公式。 一次减去公式就可以得到答案。 我认为马克的问题是,您是否认为拟合模型中的线性/二次/其他模型能够在测量之间对物体位置提供足够好的估计。
回复:线路差异不,我们只有基本的 JMP v16。
回复:线路差异与不同时间观察到的曲线进行比较的唯一方法是对每条曲线进行建模并在选定时间比较模型。 该模型可以像线性插值一样简单,也可以像 JMP 中的任何模型类型一样复杂。 您有 JMP Pro 吗? 如果是这样,您可以将数据视为“函数”并使用函数数据浏览器。
在我从您那里得知一般方法有意义之前,我不会详细介绍。