重叠时代说我有两张桌子。表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");