這是一個找到正弦波的頂部和底部峰值的示例。該腳本首先生成一些示例數據,然後去尋找頂部和底部的峰值。

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 ) );
非常感謝您花時間寫下這麼詳細的回复! 我讓它工作了,這太棒了,再次感謝你!
如果您發現有用的答案,請單擊“接受為解決方案”。 它向其他人強調此解決方案對您有所幫助。 
您好,我有一些循環運動的運動數據,以角度隨時間測量。 有沒有辦法提取最小和最大峰值(我是菜鳥,所以可以做一個簡單的解釋)。 下面是一個例子。 我一直在手動執行此操作,但我有一些包含大量峰值的數據,因此想要一種更有效的方法。 非常感謝
