重疊時代說我有兩張桌子。表A和表B.表A和表B都具有事件的事件開始和結束時間。我想生成一個新表,其中只包含表B中與表A上的事件在同一時間幀內發生的事件。是否有一種簡單的方法可以使用JSL執行此操作?
回复:重疊時代這樣運行得更快,完全符合我的需要!我也在這個過程中學到了很多關於JMP的知識。非常感激!!!回复:重疊時代您可以使用行狀態處理程序(請參閱下文)。只要匹配保持在“表B”中,當“表B”或“表A”中的數據發生變化時,就必須關注更新這些匹配。此外,即使鏈接在概念上是雙向的,如果您嘗試向“表A”添加相應的行狀態處理程序,或許不出所料,它們會相互干擾。
使用此代碼,“表B”中的選擇將傳播到“表A”:

NamesDefaultToHere(1);
dtA = NewTable("A",
NewColumn("Start", Numeric, Ordinal, Formula(RandomInteger(1, 20))),
NewColumn("End", Numeric, Ordinal, Formula(:Start + RandomInteger(1, 10)))
);
dtA << addRows(4);
dtA << runFormulas;
dtA:Start << deleteFormula;
dtA:End << deleteFormula;
dtB = NewTable("B",
NewColumn("Start", Numeric, Ordinal, Formula(RandomInteger(1, 20))),
NewColumn("End", Numeric, Ordinal, Formula(:Start + RandomInteger(1, 10)))
);
dtB << addRows(6);
dtB << runFormulas;
dtB:Start << deleteFormula;
dtB:End << deleteFormula;
// Get values into matrices
matA = dtA << getAsMatrix;
matB = dtB << getAsMatrix;
// Loop over the events in 'B' and compare each with all those in 'A' at the same time
matchesBtoA = AssociativeArray();
for(e=1, e<=NRow(matB), e++,
startB = matB[e,1];
endB = matB[e,2];
matchesInA = Loc((matA[0,1] < endB) & (startB < matA[0,2]));
matchesBtoA << InsertItem(e, matchesInA);
);
// Persist the matches in 'B', which becomes the 'master table'
dtB << New Column( "Rows in A", Expression);
for (r=1, r<=NRow(matB), r++,
Column(dtB, "Rows in A")[r] = matchesBtoA << getValue(r);
);
// This row state handler detects row selections in 'B' and selects rows in 'A'
fB =
function({sourceRows}, {Default Local},
selectedSourceRows = dtB << getSelectedRows;
rows2select = [];
for(r=1, r<=NRow(selectedSourceRows), r++,
rows2select = VConcat(rows2select, Column(dtB, "Rows in A")[selectedSourceRows[r]]);
);
dtA << clearSelect;
dtA << selectRows(rows2select)
);
// Assign row state handler to 'B'
obB = dtB << MakeRowStateHandler(fB);
回复:重疊時代謝謝!我現在已經使關聯數組工作了,它比我之前做的要快得多(即2分鐘對2小時)。
有沒有辦法我可以採用關聯數組並使用它來自動選擇表B中相應的行號?
回复:重疊時代TBH,我花了幾次嘗試(和筆和紙)才能使邏輯正確。只需在所有各種配置中繪製兩個線段(包括當A包含在B中時,或反之亦然)。實際上,這就是為什麼我添加圖表以確保我做對了!
使用矩陣運算可以使事物矢量化,這通常更快。就語法而言,matA [0,1](matA [0,2])包含表示為“A”的線段的所有起始(結束)點。'Loc()'函數返回一個列向量,給出matA中符合邏輯條件的行號。
正如丹所提到的,你可以使用<= instaed of <取決於你想要的結果。
回复:重疊時代感謝有趣的方法。我試圖圍繞以下幾行:
matchesInA = Loc((matA[0,1] < endB) & (startB < matA[0,2]));
它在做什麼,它是如何工作的?我感謝您的幫助!
回复:重疊時代我認為解決方案中的重疊條件略有不同 - 如果兩個區間僅觸摸(<=),則矩陣條件不計算重疊,而選擇Where()不計算完全包含A的B區間間隔。無論哪種方式,我認為矩陣方法會更快,但兩者都會陷入非常大的表。 要做得更好,需要一些排序和數據結構,如間隔樹 。 從JSL那樣做可能比蠻力方法更昂貴。
回复:重疊時代這可能會更好。它使用整數時間值,但沒關係。

.
NamesDefaultToHere(1);
dtA = NewTable("A",
NewColumn("Start", Numeric, Ordinal, Formula(RandomInteger(1, 20))),
NewColumn("End", Numeric, Ordinal, Formula(:Start + RandomInteger(1, 10)))
);
dtA << addRows(4);
dtA << runFormulas;
dtA:Start << deleteFormula;
dtA:End << deleteFormula;
dtB = NewTable("B",
NewColumn("Start", Numeric, Ordinal, Formula(RandomInteger(1, 20))),
NewColumn("End", Numeric, Ordinal, Formula(:Start + RandomInteger(1, 10)))
);
dtB << addRows(6);
dtB << runFormulas;
dtB:Start << deleteFormula;
dtB:End << deleteFormula;
// Get values into matrices
matA = dtA << getAsMatrix;
matB = dtB << getAsMatrix;
// Loop over the events in 'B' and compare each with all those in 'A' at the same time
matchesBtoA = AssociativeArray();
for(e=1, e<=NRow(matB), e++,
startB = matB[e,1];
endB = matB[e,2];
matchesInA = Loc((matA[0,1] < endB) & (startB < matA[0,2]));
matchesBtoA << InsertItem(e, matchesInA);
);
// Graphs
maxX = Maximum(Maximum(matA[0,2]), Maximum(matB[0,2]));
minX = Minimum(Minimum(matA[0,1]), Minimum(matB[0,1]));
NewWindow("Overlapping Intervals", << onClose(Close(dtA, NoSave); Close(dtB, NoSave)),
LineUpBox(NCol(2),
VListBox(
GraphBox(Title("Line Intervals in Table A"),
XScale(minX, maxX), YScale(0, NRow(matA)+1), YName("Row Number"), FrameSize(500, 210),
for(ii = 1, ii<=NRow(matA), ii++,
Line({matA[ii,1], ii}, {matA[ii,2], ii});
);
),
GraphBox(Title("Line Intervals in Table B"),
XScale(minX, maxX), YScale(0, NRow(matB)+1), YName("Row Number"), FrameSize(500, 210),
for(ii = 1, ii<=NRow(matB), ii++,
Line({matB[ii,1], ii}, {matB[ii,2], ii});
);
)
),
GraphBox(Title("Row numbers in Table B (in Table A) on the left (on the right)"),
XScale(0, 1), YScale(0, Maximum(NRow(matA), NRow(matB))+1), YName("Row Number"), FrameSize(500, 500),
for(ii = 1, ii<=NRow(matB), ii++,
lines = matchesBtoA << getValue(ii);
for(jj=1, jj<=NRow(lines), jj++,
Line({0, ii}, {1, lines[jj]});
);
);
)
)
);
回复:重疊時代僅供參考,我現在就是這樣做的。
OverlappingEvents = Function( {PrimaryTableName, PrimaryTableStartTime, PrimaryTableEndTime, SecondaryTableName, SecondaryTableStartTime, SecondaryTableEndTime}, {},
SecondaryTableName << Clear Selection;
For(i = 1, i <= nrows(PrimaryTableName), i++,
::PrimaryEndTime = Column( PrimaryTableName, PrimaryTableEndTime )[i];
::PrimaryStartTime = Column( PrimaryTableName, PrimaryTableStartTime )[i];
SecondaryTableName << select where( ::PrimaryStartTime <= as column(SecondaryTableStartTime) & as column(SecondaryTableEndTime) <= ::PrimaryEndTime | ::PrimaryStartTime <= as column(SecondaryTableEndTime) <= ::PrimaryEndTime | ::PrimaryStartTime <= as column(SecondaryTableStartTime) <= ::PrimaryEndTime, Current selection("Extend") ); //select all events in secondary table that overlap or are within events on primary table
);
);不幸的是,在處理大型數據表時,該功能需要很長時間。有沒有更好的辦法?
回复:重疊時代是的,兩個表都有每個事件的開始和結束時間。所以我需要一個解決方案來查找表B中的事件,這些事件在表A中的事件內部或由事件重疊。
回复:重疊時代編輯:我可能解決了與你描述的不同的問題。 在您的示例中,每行是否有(開始,結束),並且您希望將表B中的行與表A中的所有行相交?在我的例子中,表中只有一個集合(開始,結束)。
原始回复:
這是創建新表的一種方法:
seriesP = Open("$SAMPLE_DATA/Time Series/SeriesP.jmp");
seriesP_years = seriesP:Year << Get Values;
seriesP_min = Min(seriesP_years);
seriesP_max = Max(seriesP_years);
seriesR = Open("$SAMPLE_DATA/Time Series/SeriesR.jmp");
seriesR << Select Where(:Year >= seriesP_min & :Year <= seriesP_max);
seriesRsubset = seriesR << Subset("Selected Rows");