这是一个找到正弦波的顶部和底部峰值的示例。该脚本首先生成一些示例数据,然后去寻找顶部和底部的峰值。

Names Default To Here( 1 );
dt = New Table( "sine", New Column( "x" ), New Column( "y" ) );
For( k = 1, k <= 10, k++,
yfudgepos = Random Uniform( 0, .2 );
yfudgeneg = Random Uniform( 0, .2 );
For( x = 0, x <= 360, x++,
dt << add rows( 1 );
y = Sin( x / 180 * Pi() );
:x[Row()] = x + ((k - 1) * 360);
If( y < -1 * yfudgeneg,
:y[Row()] = y + yfudgeneg
);
If( y > yfudgepos,
:y[Row()] = y - yfudgePos
);
);
);
dt << select where(ismissing(:y));
dt << delete rows;
Graph Builder( Variables( X( :x ), Y( :y ) ), Elements( Points( X, Y, Legend( 3 ) ) ) );
wait(5);
// Find the min and max for each phase in the sine waves
dt << New Column("T or B",character);
// determine the starting direction of the wave
if(dt:y[1]<Y> dt:y[i],
dt:T or B[i] = "Bottom";
direction = "up";
)
);
dt << select where( :T or B != "" );
dtTB = dt << subset( selected columns(0), selected rows(1));</Y>
非常感谢你做的这些。 很抱歉提出这些愚蠢的问题,我该如何将其应用于我的数据。 您还可以解释一下为什么沿着 0 有一小步吗?
谢谢
斯蒂芬
我应该在之前的回复中更具描述性。
使用 JMP 查找正弦波峰谷的能力并不是 JMP 的内置分析之一。但是,通过使用 JMP 的脚本语言 (JSL),可以使用脚本来获取您需要的信息。
要开始解决您的问题,我需要做的第一件事就是示例数据表。JMP 在其安装中提供,但是,我不知道它们中有任何一个提供与您在初始问题中提供的正弦波相似的正弦波数据值。因此,我不得不创建自己的示例数据表。我的脚本的第一部分只是创建一个示例数据表。
Names Default To Here( 1 );
dt = New Table( "sine", New Column( "x" ), New Column( "y" ) );
For( k = 1, k <= 10, k++,
yfudgepos = Random Uniform( 0, .2 );
yfudgeneg = Random Uniform( 0, .2 );
For( x = 0, x <= 360, x++,
dt << add rows( 1 );
y = Sin( x / 180 * Pi() );
:x[Row()] = x + ((k - 1) * 360);
If( y < -1 * yfudgeneg,
:y[Row()] = y + yfudgeneg
);
If( y > yfudgepos,
:y[Row()] = y - yfudgePos
);
);
);
dt << select where(ismissing(:y));
dt << delete rows;Th
这部分脚本创建示例数据表。它不是一个完美的正弦波数据表。
我希望生成的正弦波对每个波都有一些可变性。 为实现这一点,代码会在每次高于或低于波中间时调整波。 .最终结果是一个具有不同最大高点和每个波的不同最小值的波。最终生成的数据表具有这种可变性,但它也会在波形中产生一个小台阶。虽然示例数据表并不完美,但足以使用。

这是为上述 wave 生成数据的脚本部分。
Names Default To Here( 1 );
dt = New Table( "sine", New Column( "x" ), New Column( "y" ) );
For( k = 1, k <= 10, k++,
yfudgepos = Random Uniform( 0, .2 );
yfudgeneg = Random Uniform( 0, .2 );
For( x = 0, x <= 360, x++,
dt << add rows( 1 );
y = Sin( x / 180 * Pi() );
:x[Row()] = x + ((k - 1) * 360);
If( y < -1 * yfudgeneg,
:y[Row()] = y + yfudgeneg
);
If( y > yfudgepos,
:y[Row()] = y - yfudgePos
);
);
);
dt << select where(ismissing(:y));
dt << delete rows;
它产生的表看起来像

我创建的数据表有两列。一个称为 X,一个称为 Y。列可以随意命名。只需更改脚本以将对 X 和 Y 的列名的引用换成列的实际名称。
回到我提供的实际脚本....一旦创建了数据表,我就使用 Graph Builder 以图形形式显示数据。
Graph Builder( Variables( X( :x ), Y( :y ) ), Elements( Points( X, Y, Legend( 3 ) ) ) );
此 JSL 语句显示正弦波图。
下一条语句简单地暂停了脚本的执行,让人们可以看到图表 5 秒钟,然后再继续实际搜索数据中的最小值和最大值。
Wait( 5 );
JSL 的其余部分,是代码的实际工作部分,首先找到每个正弦波的最大和最小点,然后创建一个新的数据表,其中仅包含
每个波浪的顶部和底部数据点。
// Find the min and max for each phase in the sine waves
dt << New Column("T or B",character);
// determine the starting direction of the wave
if(dt:y[1]<Y> dt:y[i],
dt:T or B[i] = "Bottom";
direction = "up";
)
);
dt << select where( :T or B != "" );
dtTB = dt << subset( selected columns(0), selected rows(1));</Y>
要将此分析应用于您的数据,您首先需要将数据输入到 JMP 数据表中,其结构类似于我生成的示例数据表。然后,假设你的数据列被命名为 X 和 Y,你只需要运行下面的脚本,让它使用你的新表来分析数据并找到每个 wave 的最小值和最大值。
Names Default To Here( 1 );
dt = Current Data Table();
// Find the min and max for each phase in the sine waves
dt << New Column( "T or B", character );
// determine the starting direction of the wave
If( dt:y[1] < dt:y[2],
direction = "up",
direction = "down"
);
For( i = 1, i <= N Rows( dt ) - 1, i++,
If(
direction == "up" & dt:y[i + 1] < dt:y[i],
Show( i );
dt:T or B[i] = "Top";
direction = "down";,
direction == "down" & dt:y[i + 1] > dt:y[i],
dt:T or B[i] = "Bottom";
direction = "up";
)
);
dt << select where( :T or B != "" );
dtTB = dt << subset( selected columns( 0 ), selected rows( 1 ) );
非常感谢您花时间写下这么详细的回复! 我让它工作了,这太棒了,再次感谢你!
如果您发现有用的答案,请单击“接受为解决方案”。 它向其他人强调此解决方案对您有所帮助。 
您好,我有一些循环运动的运动数据,以角度随时间测量。 有没有办法提取最小和最大峰值(我是菜鸟,所以可以做一个简单的解释)。 下面是一个例子。 我一直在手动执行此操作,但我有一些包含大量峰值的数据,因此想要一种更有效的方法。 非常感谢
