하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?두 개의 그래프 빌더가 포함된 창이 있는데, 두 개의 다른 데이터세트에서 가져오고, 두 그래프를 하나의 데이터 필터로 필터링하고 싶습니다. 저는 이것이 가능하다고 생각하지 않습니다. 대신 두 개의 "동기화된" 데이터 필터를 사용하는 것에 대해 생각해 보았지만, 알아낼 수 없었습니다. 지난주 JMP Discovery에서 @danschikore가 두 개의 동기화된 필터를 사용하는 가능한 솔루션으로 이벤트 핸들러를 알려주었습니다. 작동하도록 만드는 데 가까워졌지만 막혔습니다.
아래 스크립트는 두 개의 필터와 두 개의 그래프를 만듭니다. 상단 필터에서 선택한 내용이 자동으로 하단 필터에 반영되기를 원합니다. 작동하면 하단 필터를 숨기고 사용자는 두 그래프를 제어하는 하나의 필터를 볼 수 있습니다.
현재와 같이 사용자가 상단 필터에서 선택을 하면 스크립트는 "Get Where Clause"를 사용하여 해당 Where 절을 로그에 인쇄하지만, 저는 이 Where 절을 하단 필터에 적용해야 합니다. 저는 해당 Where 절 텍스트를 하단 필터에 밀어넣을 수 있는 "Set Where Clause"와 같은 명령을 원하지만, 존재하지 않는 듯합니다. 저는 텍스트 문자열(아래)을 "압축 해제"하여 하단 필터에 전달할 수 있는 양식으로 변환해야 하는 시나리오를 피하고 싶습니다.
Where( :name == \!"ALICE\!" | :name == \!"BARBARA\!" )를 선택하세요
첫 번째 필터가 두 번째 필터를 어떤 식으로든 제어할 수 있다는 것을 스스로 확신시키기 위해, 첫 번째 필터가 두 번째 필터의 선택을 지우 도록 했습니다. 즉, 두 필터 모두에 대해 말할 수 있습니다. 첫 번째 필터에서 where 절을 추출할 수 있지만 두 번째 필터에는 적용할 수 없습니다.
보너스 질문: 이 동기화가 작동하면 두 번째 필터를 숨기고 싶습니다. 스크립트의 마지막 줄은 첫 번째 필터를 숨깁니다. 대신 두 번째 필터를 숨기도록 이것을 수정하는 방법을 아는 사람이 있나요?
감사해요,
남자 이름

자동화 및 스크립팅Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?Eval(): 코드 실행 *)
Eval Expr: Expr()로 래핑된 모든 것을 미리 평가합니다. *)
Expr(): 미리 평가되어야 하는 코드를 위한 마커 *)
*) 내 뇌 : "E 단어" - 3번.
그리고 4번째는 Expr Name() 입니다. -)
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?동의하다 : )
Big Class의 경우 쉬운 해결책이 있을 수 있지만, 이 해결책은 실제 문제를 해결하는 데 도움이 되지 않을 수도 있습니다.
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?@hogi , 이 링크들에 감사합니다. Eval/Eval Expr()은 지난 몇 년 동안 저에게 JSL에서 가장 답답한 부분이었습니다. 커뮤니티에서 예제를 복사하고 조정하여 몇 번 성공적으로 사용했지만, 실제로 잘 이해했다고 느낀 적은 없습니다. 수집한 리소스 목록을 살펴보고 마침내 이해하는 데 도움이 될 수 있기를 기대합니다. 제 툴킷에 추가해야 할 부분이라는 걸 알고 있습니다.
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?제가 말하고 싶었던 것은 연결입니다. update/join을 수행하면 연도가 없는 키 데이터를 연간인 체중 데이터와 연결하게 됩니다. 새로운 그래프는 바바라의 키가 2022년, 23년, 24년에 60인치로 측정된 것처럼 보이지만, 사실은 그렇지 않습니다.
여기서 요령은 하단의 데이터는 연도와 연관이 있지만 상단의 데이터는 그렇지 않다는 것입니다. 저는 그것을 위한 중앙 막대를 원합니다. 키 대신 "학생이 태어난 시기와 장소의 1인당 GDP"를 사용했어야 했을 것입니다 -- 분명히 22/23/24와 연관이 없습니다.
위쪽과 아래쪽 그래프의 기본 데이터가 서로 다른 구조를 가지고 있기 때문에 원하는 그림(위)을 만들려면 두 개의 별도 그래프 빌더가 필요할 것 같습니다.
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?@TomF 감사합니다. 라벨 설정 제한에 맞서는 매우 멋진 기술입니다. 2개의 테이블을 사용하세요 : )
왜 이런 종류의 플롯을 개별 그래프로 생성하는 것도, 하나의 그래프로 결합하는 것도 불가능한지 궁금합니다.

한 그래프에 레이블을 설정하면 다른 그래프에도 자동으로 레이블이 표시됩니다. : (
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?다양한 필터링 기술을 알면 JMP에서 여러 가지 멋진 작업을 할 수 있습니다(특히 데이터가 많은 경우 필수적이기도 합니다).
연결이란 업데이트/조인을 의미할 수 있고 이와 같은 단일 테이블을 가질 수 있다고 가정합니다(고유 식별자가 있는 경우 가상 조인을 사용할 수 있음)

이를 통해 다음과 같은 그래프를 생성할 수 있습니다.

예를 들어 Textlet(호버 레이블)을 활용하여 이를 수행할 수 있습니다.
Graph Builder(
Size(1085, 688),
Show Control Panel(0),
Show Legend(0),
Variables(X(:Name), X(:Year, Position(1)), Y(:Height), Y(:Weight), Overlay(:Name)),
Elements(Position(1, 1), Bar(X(1), X(2), Y, Overlay(0), Legend(13))),
Elements(Position(1, 2), Line(X(1), X(2), Y, Legend(15)), Points(X(1), X(2), Y, Legend(16))),
Local Data Filter(
Add Filter(
columns(:Name),
Where(
:Name == {"AMY", "BARBARA", "CAROL", "CHRIS", "CLAY", "DANNY", "DAVID", "EDWARD", "ELIZABETH", "FREDERICK", "HENRY", "JACLYN"}
),
Display(:Name, N Items(15), Find(Set Text("")))
)
),
SendToReport(
Dispatch({}, "Name", ScaleBox, {Label Row(2, Show Major Grid(1))}),
Dispatch({}, "Graph Builder", FrameBox, {Set Textlet(Markup("Serial Number: {:Serial No.[local:_firstRow]}"))}),
Dispatch({}, "Graph Builder", FrameBox(2), {Set Textlet(Markup("Serial Number: {:Serial No.[local:_firstRow]}"))})
)
);
필요한 경우 JMP > JMP 보고서 > JMP 그래프의 호버 레이블 사용자 정의 > JMP 그래프의 호버 레이블에 텍스트 추가를 사용하여 표시되는 텍스트를 훨씬 더 많이 사용자 정의할 수 있습니다.
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?안녕하세요 @TomF , 각 단계를 설명하는 몇 가지 주석을 코드에 추가했습니다.
한 가지 방법은 Extract Expr()을 사용하는 것입니다. 표현식을 스캔하여 특정 패턴을 검색합니다.
방금 동일한 대시보드에서 4개의 추가 데이터 필터를 제어하기 위해 하나의 데이터 필터를 사용하는 오래된 스크립트를 살펴보았습니다.
그리고 그것은 다음과 같이 보였습니다
For( i = 1, i <= N Arg( filterScript ), i++,
If( Head( Arg( filterScript, i ) ) == Expr( Add Filter() ),
filterExpression = Arg( filterScript, i )
)
);
Extract Expr()을 통한 접근 방식은 훨씬 더 우아합니다. 저는 작년에 이 토론에서 @jthi 로부터 이 방법을 배웠습니다.
:folded_hands: 표현식 인덱싱: 읽기 및 쓰기 액세스
다른 트릭: Eval (Eval Expr( Expr())) - 스위스 군용 칼!
JSL에서 발생하는 문제의 95%를 해결해 드립니다.:)
JMP에서의 표현식 처리: Tipps와 Trapdoors
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?저는 그 코드의 많은 부분이 제 수준을 넘어선 것 같지만, 전반적인 아이디어는 이해합니다. 더 복잡한 상황에서는 이것을 염두에 두겠습니다. 감사합니다!
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?네, 저는 서로 다른 테이블에서 두 개의 보고서를 필터링하는 하나의 필터를 원합니다. 제가 위에서 공유한 간단한 Big Class 예제에서는 말이 안 될 것 같지만, 실제 데이터 세트의 구조를 밀접하게 모방한 더 복잡한 예제를 첨부합니다.
각 학생의 현재 키가 있는 테이블 하나와 지난 3년 동안 각 학생의 체중이 있는 테이블 하나가 있다고 상상해 보세요. 저는 다음과 같이 그 데이터를 보고 싶습니다.

키 데이터 세트는 분명히 학생 한 명당 한 행이 있습니다. 몸무게 데이터는 학생 한 명당 한 행(체중 3열)으로 시작하지만, 제가 아는 한 Graph Builder에서 몸무게를 쌓지 않고 그 하단 그래프를 만드는 방법은 없습니다. 이제 제 몸무게 표는 키 표보다 3배 많은 행이 있습니다.
데이터 필터는 두 개의 다른 테이블을 필터링할 수 없기 때문에 지금까지 제가 사용한 솔루션은 이 그래프를 만들기 위해 테이블을 연결하는 것이었습니다. 우아하지는 않지만 잘 작동합니다.
제가 정말 문제가 된 부분은 키 위에 마우스를 올리면 측정하는 동안 신발을 신었는지 여부를 팝업으로 표시하고, 몸무게 위에 마우스를 올리면 사용된 저울의 일련번호를 알고 싶어한다는 점이었습니다. 모든 데이터가 한 테이블에 있고 두 열에 Label(1)을 만들면 마우스를 올리면 값이 누락됩니다(무게 측정에는 저울 일련번호가 없기 때문)... 이 문제도 해결할 수 있지만, 그냥 매우 지저분해지기 시작했습니다.
두 개의 동기화된 필터(하나는 숨김)가 있는 두 개의 테이블에 데이터를 두는 솔루션이 훨씬 더 잘 작동할 것 같습니다. 하지만 이 그래프를 만드는 더 나은 방법이 있다면 제안을 환영합니다.
Graph Builder와 JSL로 제어하는 기능에 대한 일반적인 찬사입니다. 두 개의 서로 다른 그래프를 매끄럽게 합칠 수 있는 것은 상단 그래프의 하단과 하단 그래프의 상단에 있는 모든 것을 끄고 바로 마주보게 할 수 있는 기능이 있기 때문에 가능합니다. 이를 통해 특정 상황에서 매우 사용자 지정되고 데이터가 매우 밀집된 그래픽을 만들 수 있었습니다. 이제 우아하게 필터링할 수도 있습니다:) 다른 사람들도 나중에 이것이 유용하다고 생각할지도 모릅니다.
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?이와 같은 것에는 다양한 옵션이 많이 있으며, 모두 실제로 수행되는 작업(데이터가 어떻게 보이는지, 행 상태를 조작할 수 있는지, 무엇을 필터링하는지(그리고 그 이유))에 따라 달라집니다. 다음은 많은 경우에 (보통) 꽤 잘 작동하는 옵션 중 하나이지만 핸들러에 대한 기능이 꽤 복잡합니다(이와 같은 것에 고정 크기를 추가하는 것은(Spacer Box()의 도움으로) 일반적으로 창의 성가신 깜박임을 피하는 좋은 방법입니다).
Names Default To Here(1);
dt1 = Open("$SAMPLE_DATA/Probe.jmp");
dt2 = dt1 << Subset(All Rows, Selected Columns(0));
dt2 << Delete Rows(dt2 << get rows where(:Process == "Old"));
nw = New Window("",
Data Filter Context Box(
H List Box(
Data Filter Source Box(
df1 = dt1 << Data Filter(
Local,
Show Controls(0),
Show Modes(0),
Mode(Include(1)),
Add Filter(Columns(:Site, :Process)), Display(:Site, N Items(5))
),
),
V List Box(
gb1 = dt1 << Graph Builder(
Size(525, 458),
Show Control Panel(0),
Variables(X(:Lot ID), Y(:DELL_RPNBR)),
Elements(Bar(X, Y, Legend(4)))
),
gb2_collector = V List Box()
)
)
)
);
create_gb2 = function({a},
c = df1 << Get where clause;
If(Is Missing(c), // could also just use dt2 instead of dt2_private
dt2_privatenew = dt2 << Subset(All Rows, Selected columns only(0), Link to original data table(1), private);
,
where = Arg(Parse(df1 << Get where clause));
dt2_privatenew = Eval(EvalExpr(dt2 << Subset(
Filtered Rows(Expr(Name Expr(where))),
Selected columns only(0),
Link to original data table(1),
private
)));
If(Is Empty(dt2_privatenew), // no rows left -> pick first row and remove it, no linking
dt2_privatenew = dt2 << Subset(Rows(1), Selected columns only(0), Link to original data table(0), private);
dt2_privatenew << Delete Rows(1);
);
);
nw << inval;
Try(Close(dt2_private, no save)); // will also remove old graph builder
dt2_private = dt2_privatenew;
gb2_collector << Append(
gb2 = dt2_private << Graph Builder(
Size(528, 458),
Show Control Panel(0),
Variables(X(:Lot ID), Y(:DELL_RPNBR)),
Elements(Bar(X, Y, Legend(20)))
)
);
wait(0);
nw << Update Window;
);
create_gb2(.);
nw:handler = df1 << Make Filter Change Handler(
create_gb2();
);
Eval(EvalExpr(
nw << On Close(
Try(Close(Expr(dt1), no save));
Try(Close(Expr(dt2), no save));
Try(Close(Expr(dt2_private), no save));
);
));
Write();Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?@hogi 당신의 코드가 무슨 역할을 하는지 완전히 이해하지 못하지만, 제가 넣었더니 완벽하게 작동했습니다. 감사합니다!
솔직히 말해서, 나는 실제로 함정문에서 탈출하지 못했습니다. 나는 그 안으로 빠졌다가 다시 나왔습니다. 나는 따라갔습니다.이것커뮤니티 게시물을 봤지만 이벤트 핸들러를 변수로 저장할 이유가 보이지 않아서 저장하지 않았습니다. 작동하지 않았고, 게시물을 더 주의 깊게 따라 변수로 저장했더니 작동하기 시작했고, 무슨 일이 일어났는지 이해하지 못한 채 계속했습니다. 두 개의 함정문과 함께 코드에 주석을 달았는데, 앞으로 누군가에게 멍이 들지 않기를 바랍니다.
이 경우, 필터링은 간단합니다. 항상 열이 하나이고, 두 테이블에 동일한 x 값이 있으므로 문제가 없습니다.
위에 업데이트된 코드를 게시했습니다.
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?
@jthi 님이 쓰셨습니다:
로컬 데이터여야 하는 경우 두 개의 로컬 데이터 필터를 사용하는 것 외에도 다른 옵션이 있습니다(이것도 가능합니다).
필터 상태 핸들러는 데이터 필터의 변경에 의해서만 트리거되는 것이 아닙니다.
막대 그래프는 저장되지만, 포인트 플롯의 경우 마우스가 데이터 포인트를 터치할 때마다 상태 핸들러가 트리거됩니다!
따라서 플롯 유형에 따라 현재 필터 설정을 이전 설정과 비교하는 것이 좋을 수 있습니다. 그리고 변경 사항이 감지되면 두 번째 플롯에 해당 설정을 적용하기만 하면 됩니다.
아마 여기서 투표해 보세요:
JMP의 상태 처리기(호버 레이블, 행 상태 처리기, 필터 상태 처리기, 스케줄러 등)를 개선합니다.
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?두 테이블에 같은 값이 있는지 확인하세요!
데이터 필터가 일치하는 행을 찾지 못하면 필터가 재설정되어 모든 행이 표시됩니다.

이 문제는 JMP19에서 :folded_hands: 열 속성: 포함/강제 값을 통해 수정될 예정입니다.
<=JMP18에 대한 해결 방법으로 나머지 열에 누락된 데이터가 있는 더미 행을 추가할 수 있습니다.
-> 플롯에 나타나지는 않지만 데이터 필터가 재설정되는 것을 방지합니다.
더 보기...
//Data Filter Event Handler Test.jsl
//2024-10-31
dtHeight = Open( "$SAMPLE_DATA/Big Class.jmp" );
dtHeight << delete columns({"age", "sex", "weight"});
dtHeight << Set Name ("Height");
dtWeight = Open( "$SAMPLE_DATA/Big Class.jmp" );
dtWeight << delete columns({"age", "sex", "height"});
dtWeight << Set Name ("Weight");
dtHeight << select where(:Name == "ALFRED") << delete rows(); // <- dangerous !!!!
Try(win << Close Window);
win = New Window("Height and Weight",
Data Filter Context Box(
H List Box (
V List Box(
df1_Wt = dtWeight << Data Filter( Local,
Show Controls( 0 ), Show Modes( 0 ), Mode( Include( 1 ) ),
Add Filter(Columns(:name)),
Display( :name, N Items( 4 ))
),
df2_Ht = dtHeight << Data Filter( Local,
Show Controls( 0 ), Show Modes( 0 ), Mode( Include( 1 ) ),
Add Filter(Columns(:name)),
Display( :name, N Items( 4 ))
)
),
V List Box (
gbWt = dtWeight << Graph Builder(
Size( 612, 250 ),
Show Control Panel( 0 ), Show Legend (0), Show Title (0),
Show X Axis (0), Show X Axis Title (0), Show Footer( 0 ),
Variables( X( :name ), Y( :weight ) ),
Elements( Bar( X, Y, Legend( 6 ) ) ),
//Dispatch( {}, "Graph Builder", OutlineBox, {Set Title( "" )} ),
Dispatch({},"weight",ScaleBox,{ Max( 200 )})
),
H List Box(
Spacer Box(Size(25,200)),
gbHt = dtHeight << Graph Builder(
Size( 600, 300 ),
Show Control Panel( 0 ), Show Legend (0), Show Title (0),
Variables( X( :name ), Y( :Height ) ),
Elements( Bar( X, Y, Legend( 6 ) ) ),
Dispatch( {}, "Graph Builder", OutlineBox, {Set Title( "" )} )
)
)
)
)
)
);
eh = df1_Wt << MakeFilterChangeHandler(
function({x},
dfscript = df1_Wt << get script();
filter = Extract Expr(dfscript, Add Filter(Wild List()));
Eval(Eval Expr(df2_Ht << delete all() << Expr (Name Expr(filter)))))
);
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?데이터 필터 컨텍스트/소스 상자를 사용하여 단일 필터로 두 개(또는 그 이상)의 그래프를 필터링할 수 있지만 동일한 소스 테이블이 있어야 합니다.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
nw = New Window("Selection Filter",
Data Filter Context Box(
H List Box(
dfsb = Data Filter Source Box(
dt << Data Filter(
Local,
Add Filter(columns(:age), Display(:age, N Items(6)))
),
),
Graph Builder(
Size(208, 207),
Show Control Panel(0),
Show Legend(0),
Variables(X(:age)),
Elements(Bar(X, Legend(3)))
),
Bubble Plot(
X(:weight),
Y(:height),
Sizes(:age),
Title Position(0, 0)
)
)
)
);
이제 제 질문은 당신이 무엇을 하려고 하는가입니다. 다른 테이블에서 두 개의 보고서를 필터링하는 하나의 필터를 원하십니까? 저는 하나의 로컬 데이터 필터를 사용한 다음 그것을 사용하여 두 번째 테이블의 행을 숨기거나 제외할 것입니다(테이블을 로컬로만 수정하는 대신 테이블을 수정하도록 허용하는 경우). 로컬이어야 하는 경우 두 개의 로컬 데이터 필터를 사용하는 것 외에도 다른 옵션이 있습니다(이것도 가능합니다).
Re: 하나의 데이터 필터를 다른 데이터 필터와 미러링하려면 어떻게 해야 하나요?멋진 : )
첫 번째 상태 핸들러를 만들 때 필터 상태 핸들러를 변수에 저장하는 것을 깜빡했습니다. 그래서 핸들러가 즉시 파괴되었습니다.
그리고 인수가 0개인 함수를 사용했기 때문에 작동하지 않았습니다. -> 잘하셨습니다. 두 가지 함정에서 모두 탈출하셨습니다 : )
Set where 절이 없습니다. Where 절은 데이터 필터가 이해할 수 있는 메시지가 아니며, 행을 선택하기 위해 테이블 로 보낼 수 있습니다. 그 외에도 << Get Where 절()은 문자열을 반환합니다. Parse를 사용하여 표현식으로 변환해야 합니다.
압축 해제는 생각보다 쉽습니다. 데이터 필터에 스크립트를 요청하고 Extract Expr()을 통해 Add Filter() 부분을 추출한 다음 두 번째 필터에 적용하기만 하면 됩니다. 간단한 선택의 경우 효과적입니다. *)
eh = df1_Wt << MakeFilterChangeHandler(
Function( {x},
dfscript = df1_Wt << get script(); // store the code to create DF1 - with all the settings
filter = Extract Expr(
dfscript, // take the code which is stored in dfscript and ...
Add Filter( Wild List() ) // search for the part with Add Filter(something). Wild List() - like magic :)
);
Eval( // run the code
Eval Expr( // search for any Expr() and execute it (*)
df2_Ht << delete all() // remove all previous settings
<< Expr( // (*) find this Expr() and execute it
Name Expr( filter ) // take the code which is stored in "filter" and replace filter with the actual code
)
)
);
)
);
*) OR()을 통해 여러 필터를 결합하는 경우 스크립트에는 add Filter()가 여러 개 포함되고 Extract Expr()은 첫 번째 필터만 반환합니다.
최고의 복제 함수를 얻으려면 DF 스크립트를 구문 분석하고 모든 AddFilter()를 수집하여 두 번째 데이터 필터에 차례로 적용하면 됩니다.