统计列中符合某些条件的唯一项的数量假设在“大班”中,我想要一个公式来统计当前行中身高等于或小于当前行学生身高的不同姓名的数量。我该如何实现呢?
我有这个:
thisHeight = :height;
Col N Unique( :name, :height <= thisHeight );
我知道第二个参数是分组参数,更直观的做法是尝试限制传递给第一个参数的内容,但我到目前为止尝试的所有方法都没有成功。
数据访问回复:统计列中符合某些条件的唯一项的数量我能想到的最接近的内置函数是Col Rank( :height, < 问题是:这计算的是高度等于或低于此高度的行总数,而不是唯一名称的数量。
或者,您可以尝试使用自定义公式,例如:
thisHeight = :height; //store the current height value
// Build an associative array to collect unique names at or below thisHeight
aa = Associative Array();
For( i = 1, i <= N Rows(), i++,
If( Column("height")[i] <= thisHeight,
aa[Column("name")[i]] = 1 // This only adds to the Associative Array if this is a new, unique name
)
);
// The number of Items that have been added to the array = number of unique names
N Items( aa )
回复:统计列中符合某些条件的唯一项的数量我不确定是否可以使用 Col 函数来实现,因为新版本和旧版本的行为略有不同。
As Constant(n = :name << get values);
curheight = :height;
r = Where(:height <= curheight);
N Items(Set Unique(n[r]));
回复:统计列中符合某些条件的唯一项的数量我昨晚尝试了一个非常类似的方法,结果 JMP 卡死了。我让它运行了一整夜,今天早上起来发现 JMP 数据表窗口一片空白,没有响应。任务管理器显示机器只使用了一个核心,还有 40 多 GB 的可用内存(所以它并没有耗尽内存或占用过多 CPU)。我的表有近 40 万行数据,所以我认为这可能是一个 O(N^2) 类型的解决方案……
回复:统计列中符合某些条件的唯一项的数量@jthi关于我上面的评论,这看起来也是一个 O(N^2) 的解法。(一个错误的公式就能阻塞/崩溃整个会话,真是太糟糕了,昨天我因为尝试类似的解法而丢失了下午的大部分工作。)
很遗憾新的列函数不能正常工作,我的问题可能过于简单了,我还需要分组列,但我不知道如何在这个方案中实现它们。我可能只能用 Python 来实现,这很麻烦,因为列不会自动更新,而且 Python 脚本目前还不能保存到表中。
附:我希望每次交流都能从你身上学到一些东西
—— 为什么这种方法需要“As Constant()”函数?如果没有它会怎样?
回复:统计列中符合某些条件的唯一项的数量如果你需要公式,我不确定 Python 是否能很好地胜任。因为 Constant() 函数是为了避免在每一行都重复获取名称列表。
回复:统计列中符合某些条件的唯一项的数量考虑到各种因素,Python 解决方案奏效了,而且实现/运行速度也相当快。
仍然希望 Col N Unique() 能在未来的版本中进行改进,使其与其他函数类似。
我也希望哪里能找到一本“JMP 公式大全”,方便我们查阅。我成年后 33 年里一直在写 VBA、AppleScript、Perl、Python 和 JavaScript(以及少量 C++),JSL 是迄今为止最难学、最难理解的语言。我至今仍然不明白为什么需要 `As Constant()` 函数,也不知道它到底有什么作用。我读过大部分的脚本指南,但感觉还是需要再出一本。
回复:统计列中符合某些条件的唯一项的数量您不希望计算公式执行过程中每一行都不会改变的值。As Constant() 函数的作用就在于此,它使 JMP 只在第一行计算一次该表达式。
作为常数(expr)

我认为你基本上可以用(很可能不完全相同,但非常接近)来代替它。
If(Row() == 1,
n = :name << get values;
);
回复:统计列中符合某些条件的唯一项的数量恐怕这个问题会陷入无休止的讨论,但我还是想问最后一个问题——
列公式是否实际上只计算一次,但每次计算时每个表达式都在数组上下文中执行?
或者,整个公式是否会为每一行重新执行一次,而 Row() 函数则指定当前正在评估哪一行?
或者,我是否误解了某些更根本的东西?我对JMP处理公式的理解似乎被分割成了互不相容的部分……
回复:统计列中符合某些条件的唯一项的数量了解 JMP 内部机制的人或许能给出比我更好的答案(比如@Craige_Hales )。我把它们看作表达式(其实就是 JSL 代码),会在需要时直接对数据表的每一行进行求值。求值时机由 JMP 决定,除非我禁止求值。JMP 也做了一些优化,例如 Col 函数,它们(大多数情况下)只求值一次。
JMP帮助中心有一些有用的链接,但我只能快速找到这一个:
回复:统计列中符合某些条件的唯一项的数量以下是一种探索兔子洞的方法:
New Table( "Untitled",
Add Rows( 3 ),
New Column( "a",
Formula(Write( "\!nA" || Char( Row() ) );Row();),
Set Selected
),
New Column( "b",
Formula(Write( "\!nB" || Char( Row() ) );:c + :d + 100;)
),
New Column( "c",
Formula(Write( "\!nC" || Char( Row() ) );:a + 1000;)
),
New Column( "d",
Formula(Write( "\!nD" || Char( Row() ) );:a + 10000;)
),
new column( "e",
formula(write("\!nE" || char(row())); asconstant(write("\!nE as constant "|| char(row())); Q=a+b+c+d); Q;)
)
);
/*
A1 << A must be done first, every other column depends on A
A2
A3
D1
D2
D3
C1
C2
C3
B1 << B must be after C and D
B2
B3
E as constant 1 << the constant is calculated before the first cell, but using row 1
E1 << E must be last; the asconstant value uses all other columns
E2
E3
*/

分号 (;) 是 JSL 运算符,用于执行一系列语句并返回最后一个语句的值。这意味着可以在计算语句前添加打印/显示/写入语句,以便在日志中生成跟踪信息。
上面我了解到,asconstant(...) 是在计算第一行之前提取出来的,但当前行是第 1 行。
JMP 还会对列进行排序,以确定哪些列可以先进行评估。
回复:统计列中符合某些条件的唯一项的数量E列这样写会更合理:
New Column( "e",
formula(
Write( "\!nE" || Char( Row() ) );
As Constant( Write( "\!nE as constant " || Char( Row() ) ); a + b + c + d; );
)
)
Q 变量是不必要的,它掩盖了 AsColumn 存在的意义。
回复:统计列中符合某些条件的唯一项的数量这里还有一个链接,有时可能会有帮助(不要把所有内容都塞进一个公式里): 使用 JMP > 在 JMP 中创建公式 > 在 JMP 中创建公式

另一个好处是,如果您有多个公式,则更容易验证结果,在某些情况下还可以调试公式。