JSL을 사용하여 임의의 열을 기반으로 평균 열을 만드는 방법특정 선택 기준에 따라 열 목록을 만들고 싶습니다. 열 이름은 미리 알 수 없습니다. 그런 다음 해당 열 목록을 사용하여 각 열의 평균(또는 표준 편차 또는 개수)을 계산하는 수식 열을 만들려고 합니다.
숫자 열 전체를 처리하는 간단한 예제 스크립트입니다.
dt = Open( "$SAMPLE_DATA/Cars.jmp" );
ColList = {};
For(i=1, i<=NCols(), i++,
If(Column(i)<
<GETDATATYPE></GETDATATYPE>
<BR /> <BR /> <P>ColList는 유효한 열 목록입니다. 이 목록을 첫 번째 열의 수식에 넣으면 수식 편집기의 미리 보기에서는 올바르게 계산되지만 열은 비어 있는 상태로 유지됩니다. Mean() 함수에는 스칼라, 목록 또는 행렬을 입력해야 하는 것 같습니다(하지만 미리 보기는 어떤 경우에도 작동합니다).</P> <P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="pauldeen_0-1788272598908.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="pauldeen_0-1788272598908.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="pauldeen_0-1788272598908.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="pauldeen_0-1788272598908.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="pauldeen_0-1788272598908.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="pauldeen_0-1788272598908.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="pauldeen_0-1788272598908.png" style="width: 400px;"><SPAN class="lia-inline-image-display-wrapper" image-alt="pauldeen_0-1788272598908.png" style="width: 400px;"><span class="lia-inline-image-display-wrapper" image-alt="pauldeen_0-1788272598908.png" style="width: 400px;"><img src="https://us.v-cdn.net/6038925/uploads/images/115064i3C11FFA7C1D866DE/pauldeen_0-1788272598908.png" role="button" title="pauldeen_0-1788272598908.png" alt="pauldeen_0-1788272598908.png" /></span><SPAN class="lia-inline-image-caption" onclick="event.preventDefault();">pauldeen_0-1788272598908.png</SPAN></SPAN><SPAN class="lia-inline-image-caption" onclick="event.preventDefault();">pauldeen_0-1788272598908.png</SPAN></SPAN><SPAN class="lia-inline-image-caption" onclick="event.preventDefault();">pauldeen_0-1788272598908.png</SPAN></SPAN><SPAN class="lia-inline-image-caption" onclick="event.preventDefault();">pauldeen_0-1788272598908.png</SPAN></SPAN><SPAN class="lia-inline-image-caption" onclick="event.preventDefault();">pauldeen_0-1788272598908.png</SPAN></SPAN><SPAN class="lia-inline-image-caption" onclick="event.preventDefault();">pauldeen_0-1788272598908.png</SPAN></SPAN><SPAN class="lia-inline-image-caption" onclick="event.preventDefault();">pauldeen_0-1788272598908.png</SPAN></SPAN><SPAN class="lia-inline-image-caption" onclick="event.preventDefault();">폴딘_0-1788272598908.png</SPAN></SPAN></P> <P>두 번째 수식 열은 열 참조 주위에 AsColumn()을 추가합니다. 이미 열인 위치에 AsColumn()을 추가하는 것은 다소 직관적이지 않지만, 이제 목록, 스칼라 또는 행렬이 생성되어 mean() 수식이 제대로 작동합니다.</P> <P>제가 너무 복잡하게 생각하는 것 같습니다. 이런 요약 열을 절차적으로 생성하는 더 간단한 방법이 있을까요?</P>
제목: JSL을 사용하여 임의 열을 기반으로 평균 열을 만드는 방법일반적으로 이처럼 간단한 경우에는 Substitute를 사용하여 리스트를 다른 표현식으로 대체합니다.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Cars.jmp");
collist = dt << Get Column Names("Numeric", "String");
colrefs = Transform Each({colname}, collist,
Name Expr(As Column(dt, colname))
);
mexpr = Substitute(colrefs, Expr(List), Expr(Mean));
Eval(EvalExpr(
dt << New Column("AVG", Numeric, Continuous, Formula(
Expr(Name Expr(mexpr))
));
));
Write();
제목: JSL을 사용하여 임의 열을 기반으로 평균 열을 만드는 방법감사합니다만, 이는 간단한 문제에 대한 고급 수준의 해결책입니다. 열 수식에 열 참조를 추가하는 더 간단한 방법을 누군가 제시하는지 여전히 궁금합니다.
제목: JSL을 사용하여 임의 열을 기반으로 평균 열을 만드는 방법테이블 dt에 "TEST"라는 열이 있다고 가정해 보겠습니다. "기본"과 "TEST" 사이에는 차이점이 있습니다.
- 컬럼(dt, "TEST")
- AsColumn(dt, "TEST")
- "시험"
- 이름 Expr(As Column(dt, "TEST"))
더 보기...
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Cars.jmp");
Row() = 0; // default row value
col = "Size";
Show(col);
Show(Column(dt, col));
Show(AsColumn(dt, col));
Show(Name Expr(AsColumn(dt, col)));
Show(dt:col);
Show(AsName(col));
Write("\!N\!N");
Row() = 1;
Show(Column(dt, col)[Row()]);
Show(AsColumn(dt, col));
Show(Name Expr(AsColumn(dt, col)));
Show(dt:col);
Show(AsName(col));
어떤 유형의 해결책을 찾고 계신가요? 참조를 수식에 직접 추가할 때는 대괄호([]) 또는 행 번호([Row()])를 함께 사용해야 합니다. 열을 참조(또는 문자열) 형태로 얻는 경우, 일반적으로 수식에서 사용하려면 "열 접근" 형식으로 변환해야 합니다.
제목: JSL을 사용하여 임의 열을 기반으로 평균 열을 만드는 방법JMP에 버그 보고서를 제출했습니다.
버그는 열 수식이 `Column("name")` 인수를 허용하지 않고, `As Column()` 표현식으로 먼저 감싸야 한다는 점입니다. 시각적 수식 편집기를 사용할 때는 인수 필드에 열을 직접 입력하므로 JSL에서도 동일한 동작을 반영해야 합니다. JSL에 이 기능을 추가하면 JSL에서 열 수식을 생성하는 과정이 훨씬 간소화될 것입니다.
수식 편집기의 미리 보기 창에서는 이를 올바르게 해석하여 미리 보기를 보여주는 것 같습니다.
제목: JSL을 사용하여 임의 열을 기반으로 평균 열을 만드는 방법Column()과 AsColumn()/:colname은 서로 다른 함수이며 유사한 방식으로 사용해서는 안 됩니다.
제 생각에는 이 버그는 JSL을 사용하여 작성된 수식을 표시하는 수식 편집기에 있는 것 같습니다. 잘못된 수식(이 경우처럼)을 놓치고, 오류 메시지가 표시되어야 할 때 표시되지 않습니다.
jthi_1-1788881236165.pngjthi_1-1788881236165.pngjthi_1-1788881236165.png
jthi_2-1788881243139.pngjthi_2-1788881243139.pngjthi_2-1788881243139.png
jthi_4-1788881274171.pngjthi_4-1788881274171.pngjthi_4-1788881274171.png
이 경우 해당 내용이 열 속성에 표시되어야 합니다.
jthi_7-1788882167381.pngjthi_7-1788882167381.pngjthi_7-1788882167381.png
그리고 이것은 수식 편집기에서
jthi_6-1788882151203.pngjthi_6-1788882151203.pngjthi_6-1788882151203.png
그리고 만약 적용하려고 하면 다음과 같은 오류가 발생합니다.
jthi_5-1788882131736.pngjthi_5-1788882131736.pngjthi_5-1788882131736.png
Column()[]으로 수정하면 제대로 표시되고 정확한 결과가 반환됩니다.
jthi_0-1788880964367.pngjthi_0-1788880964367.pngjthi_0-1788880964367.png
하지만 이것이 어떻게 동작해야 하는지는 JMP 개발자들이 결정할 문제입니다.
제목: JSL을 사용하여 임의 열을 기반으로 평균 열을 만드는 방법Jarmo는 좋은 지적을 해주었고 Column("name")[]을 사용하는 대안 솔루션을 제시했습니다. Jarmo가 언급했듯이 Column("name")[]을 사용하면 수식 편집기에서 보기 좋지 않습니다. 아래 제 해결책은 해당 옵션에 대한 내용은 다루지 않지만, 많은 사용자가 왜 이 부분에서 혼란스러워하는지 설명합니다. Jarmo가 이미 게시한 내용과 상당 부분 겹치지만, 이미 작성해 둔 내용이라 덧붙입니다.
사실 원글 작성자가 제시한 스크립트는 버그가 아닙니다. 이는 예상되는 동작이며, 많은 사용자가 열 참조 방식과 열 수식 평가 방식에 대해 혼동하는 부분을 보여주는 예시입니다.
혼란의 핵심은 `Column("name")` 구문과 `:name` 구문의 차이를 이해하는 것입니다. 둘 다 특정 상황에서 열을 참조하는 유효한 방법이지만, 반환 값은 다릅니다. 구체적으로, `Column("name")`은 열 객체에 대한 참조를 반환하는 반면, `:name`은 현재 행의 `name` 열에 있는 값을 반환합니다. 참고로, `:name`은 `As Column("name")` 함수의 연산자 형태입니다. 즉, 둘은 완전히 동일한 기능을 합니다.
다음 예제 스크립트를 통해 이를 설명하겠습니다. 이 스크립트는 JMP 세션에서 Cars.jmp 데이터 테이블이 열려 있고 최신 상태라고 가정합니다.
Names Default To Here(1);
dt = Open( "$SAMPLE_DATA/Cars.jmp" );
// sending messages to a column; either syntax works
Column(dt, "Year") << Set Property("Range Check", LELE(87, 97));
dt:Head IC << Set Property("Spec Limits", {LSL( 150 ), Show Limits( 1 )});
// Return values
// returns a column object reference shown as Column( "Year" ) in log
Column(dt, "Year"); // returns Column( "Year" )
// returns value in Year column on the current row.
// Since current row is 0 (the default invalid row number), returns missing (.)
:Year; // returns .
// Set the current row to the first row
Row() = 1;
:Year; // returns 87
위 정보를 고려하면 JMP가 열 참조 집합의 평균을 계산할 수 없다는 점이 분명해집니다. 이것이 바로 첫 번째 열의 수식이 제대로 평가되지 않는 이유입니다. Mean() 함수는 값을 필요로 하는데, 이 값은 두 번째 열의 수식에 제공됩니다. 데이터 테이블이 열 수식을 평가할 때, 현재 행을 1로 설정한 다음 Formula 속성에 저장된 식을 평가합니다. 반환 값을 현재 행의 해당 열 셀에 입력합니다. 그런 다음 현재 행을 다음 값으로 설정하고 이 과정을 반복합니다. 이 단계는 마지막 행에 대해 수식이 평가될 때까지 반복됩니다. 따라서 열 수식의 구문은 데이터 테이블의 각 행에 대해 평가될 수 있어야 합니다.
제 생각에 제공해주신 예제 스크립트에서 예상치 못한 결과가 하나 있습니다. 바로 `As Column(Column("name"))` 구문이 `As Column("name")`과 동일하게 평가된다는 점입니다. 오류가 발생할 것으로 예상했지만, JMP는 이를 허용하고 의도를 정확하게 해석합니다. 이는 형식적인 프로그래밍 언어에 비해 스크립트 언어가 갖는 (때때로) 장점입니다. 하지만 향후 오류가 발생할 가능성이 있으므로 이 구문을 사용하는 것은 권장하지 않습니다.
제공된 예제 스크립트를 고려할 때, 목표를 달성하는 가장 좋은 방법은 첫 번째 접근 방식을 열 수식에서 제외하고 두 번째 접근 방식을 사용하는 것이라고 생각합니다. 추가적으로, ColList를 열 참조 대신 열 이름 목록으로 정의해야 합니다. 다음은 수정된 예제 스크립트로, 안정적으로 작동할 것입니다.
dt = Open( "$SAMPLE_DATA/Cars.jmp" );
ColList = {};
For( i = 1, i <= N Cols(), i++,
If( Column( i ) << GetDataType == "Numeric",
Insert Into( ColList, <FONT color="#FF6600"><STRONG>Column( i ) << Get Name</STRONG></FONT> )
)
);
MeanExpr2 = Name Expr( Mean() );
For( i = 1, i <= N Items( ColList ), i++,
Insert Into( MeanExpr2, Name Expr( As Column( ColList[i] ) ) )
);
Eval( Eval Expr( dt << New Column( "Average of numerics 2", Formula( Expr( Name Expr( MeanExpr2 ) ) ) ) ) );
제목: JSL을 사용하여 임의 열을 기반으로 평균 열을 만드는 방법이론적인 관점이나 실제 구현 방식에서는 말씀하신 내용이 전적으로 맞을 수도 있겠지만, 사용자 인터페이스의 동작 방식은 그렇지 않습니다. 테이블에서 열을 선택해서 mean() 연산자에 드래그하면 계산이 제대로 됩니다. 하지만 스크립팅에서는 열을 직접 선택할 수 없고, 열 이름에 해당하는 문자열 객체를 선택한 다음 JSL에게 해당 객체를 열 참조로 해석하도록 지시해야 합니다. 그리고 나서 이 참조를 mean() 연산자에 삽입해야 합니다. JSL 연산자에서 Column("Name")을 행에 인덱싱할 수 있는 열 객체로 처리하도록 개선하면 훨씬 직관적이고 사용자 인터페이스의 동작 방식과 유사하게 작동할 것입니다. 말씀하신 대로 이 부분에 대한 사용자들의 혼란이 상당합니다.
그리고 Jarmo의 지적대로 수식 편집기의 오류 메시지는 명확성과 일관성을 개선해야 합니다. 다시 한번 말씀드리지만, Column("Name") 구문을 사용할 때 미리 보기에서는 올바르게 평가되는 것처럼 보이지만 실제 수식은 평가되지 않습니다.