为什么选择/取消选择行会触发重新计算列公式?我有一个大约有 100,000 行和 2000 列的数据表。其中数十列包含公式。当我在某处进行更改时,我注意到状态栏显示“正在评估 ##column_xyz”,并且它会继续评估数据表中的每个公式。由于这是一个相当大的表并且有很多公式,因此计算所有公式最多需要 60 秒。因此,我对执行触发公式计算的操作非常敏感,因为用户界面将变得无响应,直到完成为止,并且当它意外发生时,这可能会非常烦人。另一方面,我不想一直“抑制公式评估”,因为有时我会忘记它,并且数据不会在应该更新的时候更新。
因此,在这个大型数据表上,我有一个 JSL 脚本,它使用 Graph Builder 平台生成一组图表,应用一些本地数据过滤器,对数据执行一些选择性突出显示。本质上,该脚本的目的是动态生成图表并准备将其剪切并粘贴到电子邮件或报告中。
我注意到这个脚本似乎需要很长时间才能运行。比应有的时间要长。在图表最终出现之前,UI 有近 60 秒的时间没有响应。我花了一些时间试图弄清楚这 60 秒内发生了什么。然后我突然意识到这个脚本以某种方式触发了公式评估。这并不是很明显,因为数据表状态栏没有显示正常的“正在评估...”消息;它保持空白,大概是因为评估是由脚本而不是用户操作触发的。当我在“脚本日志”窗口打开时运行脚本时,日志状态栏显示“正在评估 ##column_with_formula”。日志状态栏被冻结在该消息上,尽管延迟的持续时间让我相信它实际上正在评估表中的每个公式列。然后我通过为整个表启用“抑制公式评估”并再次运行脚本来确认公式评估是罪魁祸首 - 图表几乎立即出现。
通过反复试验,我将其范围缩小到脚本中的一行 - “选择位置”用于突出显示生成的图表上的一些数据。它看起来像这样:
myDT << Select Where( :Name("##column_with_formula") == "value" );我觉得这很奇怪;也许它与“哪里”部分有关。所以我用更简单的东西替换了这一行:
myDT << Select Rows( {1,3,5,7} );甚至这句台词似乎仍然在幕后触发公式评估。然后我又做了一些实验:
- 打开任务管理器后,我以正常方式触发公式评估(更改列中的值)。状态栏显示正在评估的公式,我的 CPU 使用率立即飙升至 30%(一个 CPU 核心最大化)。
- 我等待活动停止,然后尝试使用 UI 在数据表上选择一行。状态栏没有变化;它仍然显示“已完成评估”。但任务管理器显示的 CPU 活动与正在发生公式计算时完全相同。
- 我为数据表启用了“抑制公式评估”,并在数据表上选择了不同的行。CPU 使用率没有飙升。
总而言之,通过实验我证明了以下内容:
- JMP 多余地执行列公式评估;与用户界面的基本交互会导致计算在后台进行,即使实际上没有修改任何输入数据。
- JMP 对于何时执行这些公式评估并不透明。状态栏有时会显示一条消息,但大多数时候没有任何迹象表明这种情况正在发生。这通常表现为用户界面无明显原因的滞后/卡顿/无响应。
- 似乎如果触发一列进行评估,则所有列都会被评估,无论它们是否需要它。
对于较小的数据集和较少且不太复杂的公式,过多的公式评估似乎不是问题。但如果公式足够复杂,数据集很大,这确实会成为一个障碍。就我而言,我想我将不得不适应始终抑制公式评估并且仅手动评估公式。但这很容易出错,就像在 Excel 中将工作簿重新计算设置为手动一样。至少 Excel 有一个依赖树,允许它仅评估已更改数据的必要公式,并且如果用户适当地设计公式,则可以始终以最小的开销将计算保留在自动状态。诚然,我对 JMP 的熟悉程度不如对 Excel 的熟悉程度,因此在 JMP 中可能有一些我还没有学会的处理此问题的方法。
有人对如何管理大量复杂公式而不一直抑制 eval 有什么建议吗?
另外,正如我的文章标题中所述,我有兴趣知道为什么行选择触发公式 eval 发生变化。另外,为什么 JMP 有时会告诉您它正在计算公式,有时会隐藏它?
回复:为什么选择/取消选择行会触发重新评估列公式?@克里斯_罗德里格斯写道:
此外,对我来说最令人惊讶的部分是,仅仅选择行触发了全表重新评估(CPU 使用率和 UI 响应能力证明了这一点)。如果公式可能会受到排除行的影响,为什么不在用户实际使用时触发计算排除一行?我想理论上用户可以编写一个取决于当前行选择状态的列公式,但这对我来说似乎是一种罕见的边缘情况。
这也让我很困惑。 为什么 Jmp 不区分行状态:排除和已选择?
即使行状态已更改 - 可能会进行后续检查以查看是否排除()状态发生了变化。
我同意@克里斯_罗德里格斯- 大多数列公式都会使用排除()并不是已选择() 。
[但是,那些具有已选择()是最酷的:)]
听起来不像是一个小众问题。 对于5-1000行数据的样本数据来说,这并不是什么大问题。
但对于较大的数据集,用户使用排除()在列公式中要付出巨大的惩罚!
Names Default to Here(1);
dt = new table("test", add rows(5),
New Column( "again"),
New Column( "excluded",
Formula(
:again[1] = 1;
Excluded();
),
));
回复:为什么选择/取消选择行会触发重新评估列公式?好吧,很高兴终于听到我不是唯一一个为此苦苦挣扎的人。差不多四年过去了,这种情况仍然没有得到任何改善。有各种奇怪的情况会触发整个数据表上的公式求值,即使公式求值据说在表范围内被抑制。抑制单个列上的公式 eval 是行不通的,因为无法处理依赖关系。必须取消抑制所有列,JMP 才能按正确的顺序评估它们。此外,在 JMP16 中,公式评估引擎甚至似乎变得更慢。现在评估我的整张桌子需要花费不合理的时间。
在此基础上,再加上这些论坛中不断提出的删除所有公式并仅存储固定值的建议,我得出的结论是,JMP 根本不适合处理动态公式,而只能处理静态数据。公式一开始很好,当你的表很小并且它们仍然可以正常工作时,但是当公式计数、公式复杂性或行数超过一定限制时,你就会碰壁。我将不得不使用其他一些工具完全重新设计该项目,并仅使用 JMP 进行绘图/演示/统计。
我将把这个问题标记为已解决。解决办法就是没有解决办法。如果您遇到此问题,那么 JMP 不是适合该工作的工具。删除动态公式并仅存储静态数据。
回复:为什么选择/取消选择行会触发重新评估列公式?我对大型数据表也有类似的问题。
一次又一次地触发公式评估。
保存表并重新打开后,一切正常。
因此,重新评估可能是由变量名称冲突触发的。 U重置变量名称后问题就消失了。
如果其他用户也有类似的问题,这里希望快速启用和禁用单个公式:
启用/禁用公式计算的快速方法
另一个想法:默认禁用公式评估 - 获得平滑的 Jmp,而无需此类虚假的公式重新评估。
如果向数据表添加一些数据,只需触发一次性公式评估。 这是愿望:
触发特定公式的一次性公式评估的快速方法
回复:为什么选择/取消选择行会触发重新计算列公式?该表不是在旧版本的 JMP 中创建的。它可能已经有一年了,所以它是 JMP 13 或 14。
我使用红色小三角菜单检查表的抑制评估框,然后保存并关闭它。重新打开表后,不再选中抑制评估框,因此表范围的设置显然没有通过保存表来保留。当表格打开时,状态栏立即显示“正在评估 xyz...”。我不确定是什么触发了这种情况的发生。
我有一个 OnOpen 脚本,用于将数据填充到某些数据查找函数中使用的某些关联数组中。我将 OnOpen 重命名为其他名称以禁用它,这样当我打开表时它就不会触发,但评估仍然会发生。
我编写了一个 JSL 脚本来进入大多数公式列的列属性并在那里抑制 eval,因为我知道保存表时会保留此选项。 所以现在全表评估几乎不需要那么长时间。我想这就是我从现在开始处理它的方式:抑制单个列上的 eval,当我导入需要运行公式的新数据时,使用脚本暂时取消抑制它们。
回复:为什么选择/取消选择行会触发重新计算列公式?我无法制作一个在打开时具有计算公式的表格。@中伟
该首选项可能会对在 JMP 5 左右创建的 JMP 表产生影响。我目前看不到它有任何作用。
可以使用数据表的红色小三角选项来抑制公式求值并将表保存在该状态(包含部分求值的列)。 您可以使用同一红色三角形中的 rerunFormulas 来强制更新(或来自 JSL)。 (这可能就是您所要求的。)
省长说的原因不建议当表设置了抑制位时,它会变得非常混乱吗?或者它曾经这样做过。
如果您寻求技术支持,他们将输入并跟踪缺陷(或找出为什么存在该首选项以及它对旧格式表做了什么。)
没有调试/日志记录框架。
回复:为什么选择/取消选择行会触发重新评估列公式?Craige,在计算公式时写入日志是个好主意。我将使用此技术来进一步解决项目中与公式计算相关的 UI 滞后和延迟问题。我的方法没有那么精确。但我确实有一个问题 - JMP 中是否有我可以打开的“调试”模式或“详细日志记录”功能?如果我不必在代码中放入如此多的 Write 语句只是为了弄清楚 JMP 在任何给定时刻正在做什么,那就太好了。
然而,目前我仍然需要按原样使用这个项目来完成我当前的工作。我只想完全抑制公式计算并根据需要手动重新运行公式。即使我在首选项菜单中启用了“禁止打开时求值”,JMP 仍会在我打开表格时立即求值公式。有没有办法完全阻止该表上的所有自动公式评估?如果此首选项应该执行此操作但它不起作用,有什么方法可以提交错误报告?
仅供参考,我在 Windows 10 x64 上使用 JMP PRO 14.1。
回复:为什么选择/取消选择行会触发重新计算列公式?您运行的是哪个版本的 JMP?
据我所知,14 正在做我所期望的事情;这是我的测试 JSL
New Table( "Untitled", add rows(3),
// EVERYTHINGCOL depends on everything. it evaluates last.
New Column( "EVERYTHINGCOL", Formula( Write( "\!nEVERYTHINGCOL,row" || Char( Row() ) ); :ROWSTATECOL + :INDEPCOL + :DEPONINDEP; ) ),
// DEPONINDEP depends on INDEPCOL, but not ROWSTATECOL.
New Column( "DEPONINDEP", Formula( Write( "\!nDEPONINDEP,row" || Char( Row() ) ); :INDEPCOL + 1; ) ),
// INDEPCOL is independent. It evaluates early, maybe first.
New Column( "INDEPCOL", Formula( Write( "\!nINDEPCOL,row" || Char( Row() ) ); 17; ) ),
// ROWSTATECOL is directly dependent on row state information. It evaluates early, maybe first.
New Column( "ROWSTATECOL", Formula( Write( "\!nROWSTATECOL,row" || Char( Row() ) ); Selected( Row State() ); ) ),
)
查看日志;各专栏在评估时进行报告。 选择行会导致其中两列进行计算,但另外两列不会进行计算。
回复:为什么选择/取消选择行会触发重新评估列公式?在“表”下的“首选项”菜单中,有一个“打开时禁止公式评估(不推荐)”的选项。我打开了这个选项,但它似乎不起作用。当我打开数据表时,它开始时公式 eval 未被抑制,我仍然需要手动抑制。这个选项是否损坏或者我误解了它应该做什么?
回复:为什么选择/取消选择行会触发重新评估列公式?Craige,我的观点是所有公式都会重新计算它们是否依赖于行状态。绝大多数公式与行状态没有任何关系,但行状态的更改无论如何都会导致它们重新计算。我想 JMP 会一直计算一切,如果发生任何可能影响可能存在的任何类型公式的事情。在我看来,这是不必要且低效的。就像当手术刀就足够时却使用战斧一样。我相信用这种方式编写程序会更容易;这似乎是一种简单的方法,当我得知这就是 JMP 处理公式评估的方式时,我感到很惊讶。
现在我更好地了解了公式的计算方式,我当然可以通过抑制公式 eval 并插入 dt << runFormulas; 来解决它。等待(0);在我的脚本中声明。它不会很漂亮,但我想它会起作用。
回复:为什么选择/取消选择行会触发重新评估列公式?是的,如果任何公式依赖于行状态信息,则更改行选择将重新评估该列以及依赖于它的任何列。
在行状态更改后使用 dt<回复:为什么选择/取消选择行会触发重新评估列公式?
吉姆,谢谢你的回复。该表包含时间序列数据,我定期导入最新数据。我想保留公式,以便在将新数据添加到表中后计算它们。
对于大多数这些公式,该值仅取决于同一行中的其他数据。排除表中前面的数据不会对下面的值产生任何影响,因此无需重新计算整个列,但无论如何都会发生。如果只有当公式包含 Col Maximum() 或 Lag() 或其他此类函数(会导致公式受到其他行中的值的影响)时才会发生这种情况,那就太好了。
此外,对我来说最令人惊讶的部分是,仅仅选择行触发了全表重新评估(CPU 使用率和 UI 响应能力证明了这一点)。如果公式可能会受到排除行的影响,为什么不在用户实际使用时触发计算排除一行?我想理论上用户可以编写一个取决于当前行选择状态的列公式,但这对我来说似乎是一种罕见的边缘情况。
回复:为什么选择/取消选择行会触发重新评估列公式?重新计算已完成,因为公式可能会受到给定列的单元格选择/排除更改的影响。考虑到数据表的大小,我会考虑更改公式值不会更改的任何列,然后删除“公式”属性,将它们变成典型的数字列。