你好,我是任何語言腳本編寫的初學者。我目前正在漫無目的地完成一項我認為簡單的練習任務。我正在使用 JMP18。我的目標是使隨著時間推移處理不斷增長的資料集的常規操作實現自動化。常規操作是先確定時間尺度,然後針對大型資料集顯示該時間尺度上的資料變化。我解決這個問題的基本方法是創建新列來填充所有初始數據,並在更多列上使用公式來獲取差異。如果有人有更好的建議,我將不勝感激。以下是我所在的位置:
本質上,我有一組數據,我想實現以下目標。
1)我希望取得日期和時間列,將它們合併到一列中,然後找到最小值,並使用它來建立開始日期。然後我可以減去時間來查看數據之間的時間差異。使用 formula() 函數,這一切都變得非常簡單。這裡的一切都很棒。
2)我想對幾個資料列做類似的事情,但我無法像之前那樣找到初始值。初始資料由我之前對第三列中每個唯一項目(在下面的程式碼中稱為 Unique_Fruit)所找到的最短時間決定。為了這個論壇的利益,對於每個unique_fruit,我想創建一個包含該水果數據初始值的列,以便我可以快速計算出來自實際數據列的變化。
我目前的 JSL 腳本如下。我有一個虛擬程式碼公式,但我還不知道該做什麼。這是我使用 If 函數、發現時間相等並僅為那些單元格設定值的步驟。我最初的想法是嘗試使用 for 循環並在公式中進行迭代,但這似乎不起作用。
DataTable = Current Data Table();
New Column( "Date Number Format", Numeric, "Continuous" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Date Number Format[i] = Num( DataTable:Key_Date[i] );
);
New Column( "Time Number Format", Numeric, "Continuous" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Time Number Format[i] = Num( DataTable:Key_Time[i] );
);
New Column( "Current_Time", Numeric, "Continuous" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Current_Time[i] = DataTable:Date Number Format[i] + DataTable:Time Number Format[i];
);
New Column( "Unique_Fruit", Character, "Nominal" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Unique_Fruit[i] = DataTable:Fruit[i] || "-" || DataTable:Type[i];
);
New Column( "Starting_Date_Number_Format", Numeric, "Continuous",
Formula( Col Minimum( :Current_Time, :Unique_Fruit ) )
);
New Column( "Minutes", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Minute", "fractional" ) )
);
New Column( "Days", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Day", "fractional" ) )
);
New Column( "Weeks", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Week", "fractional" ) )
);
New Column( "Months", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Month", "fractional" ) )
);
New Column( "Initial_Taste", Numeric, "Continuous",
Formula(
If( :Current_Time == :Starting_Date_Number_Format, :Key_Taste, . )
)
);
For( i = 1, i <= N Rows( DataTable ), i++,
If( DataTable:Current_Time[i] == DataTable:Starting_Date_Number_Format[i],
DataTable:Initial_Taste[i] = DataTable:Key_Taste[i];
);
);
New Column( "Delta_Taste", Numeric, "Continuous",
Formula( :Key_Taste - :Initial_Taste )
);
New Column( "%_Change_Taste", Numeric, "Continuous",
Formula( ( :Delta_Taste / :Initial_Taste ) * 100 + 100 )
);</CODE></P><BR /></LINGO-BODY><LINGO-LABS id="lingo-labs-844919" slang="en-US" mode="CREATE"><LINGO-LABEL>自動化和腳本</LINGO-LABEL></LINGO-LABS><LINGO-SUB id="lingo-sub-844929" slang="en-US" mode="CREATE">回覆:初學者嘗試編寫腳本/如何在公式函數內進行迭代?</LINGO-SUB><LINGO-BODY id="lingo-body-844929" slang="en-US" mode="CREATE"><P>您能提供帶有正確答案的範例資料集+列嗎?最有可能的是,您可以使用類似這樣的方法來取得初始值,但您必須修改比較,因為這個比較會取得每個類別的第一個值</P>
<BR />
<PRE><CODE class=" language-jsl">Col Cumulative Sum(If(Row() == Col Min(Row(), :age), :height, .), :age)
其中:age 是 unique_fruit 且:height 是您的值欄位。您也可以利用 Lag() 和變數。
我也會對你的腳本做一些修改,使其更加健壯。
- 使用名稱預設為此處 (1) 啟動腳本;
- 正如您引用資料表一樣,使用它
- 資料表<<新列(...
- 我也會考慮將 DataTable 更改為 dt 或類似名稱,因為 JMP 具有名為 Datatable() 的函數
- 循環遍歷資料表時使用 For Each Row 而不是 For,因為這是它的特殊用例
- 當您希望在 JMP 表中新增欄位而不使用公式時,您有以下幾個選項:
- 使用新欄位 + 公式 + 執行公式 + 刪除公式組合
- 建立新列並循環遍歷資料表(就像您正在做的那樣)
- 然後有一點挑剔的方法,使用<<應用公式,但我會先堅持這些(通常我使用第一個)
謝謝你的建議。我正在嘗試模擬資料集以及我目前手動執行的操作。為了設定初始值,我查看每個唯一項目並從該單元格中呼叫資料並填充整個列,以便我可以繼續計算的下一部分。我也會嘗試根據您的建議更新腳本的其餘部分,但我認為主要問題尚未解決(或者我還沒有明白)。
這個問題沒有得到解決,因為創建模型資料通常比回答正確的問題花費更多時間。您應該能夠利用類似這樣的方法來取得初始值
Col Min(If(:Date Number Format == Col Min(:Date Number Format, :Unique_Fruit), :Key_Taste, .), :Unique_Fruit)
這不是構建這些的唯一方法,但這樣的方法確實經常有效
非常感謝。只是為了澄清一下,我並不是想把責任推到你的第一次回應上,更多的是我試圖在幾次迭代中實現它,但認為我仍然遺漏了一些東西。我應該繼續下去,因為我可能最終會得到你在這裡展示的答案,但正如我之前所說,我對編寫這些內容的腳本還不熟悉,所以進展很慢。
出於好奇,為什麼會有“。”在其他方面?
缺失值是為了嘗試「強制」Col Min 只有一個選項可供選擇,因為它將忽略缺失值。
您可以將此類公式分解為多個部分,以便更好地理解它們(有時它們仍然可能非常隱晦)
//col1
Col Min(:Date Number Format, :Unique_Fruit)
//col2
:Date Number Format == :col1
//col3
If(:col2, :Key_Taste, .)
//col4
Col Min(:col3, :Unique_Fruit)

嘿,我在玩這個的時候有了額外的想法。如果我想做一些更接近我發布此文時最初想做的事情,該怎麼做?我所在的位置是編寫一個儲存列表的變量,然後嘗試讓程式碼遍歷該列表來填充公式。而不是將變數填入公式中,而是更新為列表值之一。這是可以在公式函數中完成的事情嗎?
感謝您在此的解釋。我正在嘗試這個方法,繼續我自己的這個小項目,看看我能把它帶到哪裡。
您可以取得公式中的值列表/收集公式中的值列表,但您必須小心如何更新值(使用 As Constant 或 If(Row() == 1,...) 可以有所幫助)。您可能還想避免公式內的循環,因為它們確實經常觸發。
您可以使用 Lag(),但這需要對資料進行排序(無需排序即可完成,但很快就會變得複雜),但通常的想法有點像這樣
If(Row() == 1,
init_taste = :Key_Taste
);
If(:Unique_Fruit != Lag(:Unique_Fruit),
init_taste = :Key_Taste;
);
init_taste;
請注意,我確實按日期數字格式和Unique_Fruit對資料進行了排序。