겹치는 시간두 개의 테이블이 있다고 가정 해보십시오. 표 A 및 표 B 모두 표 A 및 B에는 이벤트에 대한 이벤트 시작 및 종료 시간이 있습니다. 테이블 A의 이벤트와 같은 시간대에 발생하는 테이블 B의 이벤트 만 포함하는 새 테이블을 생성하고 싶습니다. JSL에서이 작업을 수행하는 쉬운 방법이 있습니까?
제목 : Re : 중복 시간이것은 훨씬 빨리 실행되며, 정확히 내가 필요로하는 것입니다! 또한이 과정에서 JMP에 관해 많은 것을 배웠습니다. 매우 감사!!!제목 : Re : 중복 시간행 상태 핸들러를 사용할 수 있습니다 (아래 참조). '표 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);
제목 : Re : 중복 시간고맙습니다! 나는 이제 연관 배열 작업을 만들었고, 이전에했던 것보다 훨씬 빠릅니다 (즉, 2 분 대 2 시간).
연관 배열을 사용하여 표 B에서 해당 행 번호를 자동으로 선택하는 데 사용할 수있는 방법이 있습니까?
제목 : Re : 중복 시간TBH, 논리적 인 권리를 얻으려면 몇 가지 시도 (그리고 펜과 종이)가 필요했습니다. 다양한 구성 (A가 B에 wholy가 포함되어 있거나 그 반대의 경우 포함)에서 두 개의 선분을 그립니다. 실제로, 그게 내가 그래프를 추가했기 때문에 내가 옳았음을 확신 할 수있다.
행렬 연산을 사용하면 일반적으로 더 빠른 벡터화 작업을 수행 할 수 있습니다. 구문의 관점에서, matA [0,1] (matA [0,2])는 'A'로 표시된 선분에 대한 모든 시작 (끝) 점을 포함합니다. 'Loc ()'함수는 논리 조건이 충족되는 행 번호를 matA에 제공하는 열 벡터를 반환합니다.
Dan이 언급했듯이 결과를 원할 때 <를 사용할 수 있습니다.
제목 : Re : 중복 시간흥미로운 접근 방식을 가져 주셔서 감사합니다. 내 머리를 다음 줄로 감싼다.
matchesInA = Loc((matA[0,1] < endB) & (startB < matA[0,2]));
그것은 무엇이고 어떻게 작동합니까? 도와 줘서 고마워!
제목 : Re : 중복 시간솔루션의 오버랩 조건은 약간 다릅니다 - 두 간격이 만지면 (<대 <=) 매트릭스 조건이 겹침을 계산하지 않으며 Select Where ()가 A를 완전히 포함하는 B 간격을 계산하지 않습니다. 간격. 어느 쪽이든 나는 매트릭스 접근법이 더 빠를 것이라고 생각하지만, 둘 다 매우 큰 테이블에 대해서는 늪을 피울 것이다. 훨씬 더 잘하려면 몇 가지 정렬 및 데이터 구조가 필요합니다. 간격 트리 . JSL에서 그렇게하는 것은 무차별 방식보다 더 비싸다.
제목 : Re : 중복 시간이것은 더 좋을 수도 있습니다. 정수 시간 값을 사용하지만 괜찮습니다.

.
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]});
);
);
)
)
);
제목 : Re : 중복 시간참고로, 지금 내가 지금하고있는 방법이다.
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
);
);불행히도이 함수는 큰 데이터 테이블로 작업 할 때 매우 오랜 시간이 걸립니다. 더 좋은 방법이 있습니까?
제목 : Re : 중복 시간예, 두 테이블 모두 각 이벤트의 시작 및 종료 시간을가집니다. 그래서 나는 테이블 A에있는 이벤트에 의해 겹쳐진 테이블 B의 이벤트를 찾아내는 솔루션이 필요합니다.
제목 : Re : 중복 시간편집 : 아마도 당신이 설명하는 것보다 다른 문제를 해결했습니다. 귀하의 예제에서 각 행은 (시작, 끝)을 가지며 테이블 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");