일관성 없는 허용 가능한 구문AllCols = dt << Get Column Names();
AllColNames = dt << Get Column Names(string);
for(i=3, i<=n items(AllCols), i++,
colcol = AllCols[i];
cname = AllColNames[i];
nnm1 = Col Number(colcol);
Fstr = "num(:\!""||cname||"\!"n)";
Fexpr = parse(Fstr);
newcol = dt << new column("Temp", numeric, formula(eval(evalexpr(Fexpr))));
nnm2 = Col Number(newcol);
if(nnm2 == nnm1,
newcol << delete formula();
dt << Delete Columns(colcol);
newcol << set name(cname), //else
dt << Delete Columns(newcol);
);
);저는 Windows에서 JMP18을 사용하고 있습니다. 자주 사용하고 싶은 코드를 작성할 때는 툴바 버튼을 만들고 싶습니다. 하지만 가끔은 열린 스크립트 창에서 실행하기에는 괜찮은 코드가 툴바 아이콘에서 실행하면 안 되는 경우가 있습니다. 다음은 모든 항목이 숫자인 경우 열을 반복하고 문자에서 숫자로 변경하는 예입니다. 툴바에서 실행할 때 이의가 제기되는 부분은 다음과 같습니다.
newcol = dt << new column("Temp", numeric, formula(eval(evalexpr(Fexpr))));
스크립트 창에서 실행하면 이 구문이 허용됩니다!
각 상황에서 jsl 인터프리터가 왜 다를까요?
이에 대한 어떤 구문이 보편적으로 받아들여질까요?
매우 큰 데이터 세트와 열의 경우 느릴 수 있습니다. 이를 수행하는 더 나은 방법이 있습니까?
자동화 및 스크립팅데이터 블렌딩 및 정리윈도우Re: 일관되지 않은 허용 가능한 구문어떤 오류 메시지가 나왔나요? 스크립트 창에는 현재 데이터 테이블이 있지만 툴바 스크립트에는 없을 수 있다고 생각합니다. 그냥 추가하면 될 수도 있습니다.
currentDatatable(dt);
대본의 시작부분에 넣으면 충분해요.
당신은 할 수 있습니다
print(currentDatatable());
스크립트 시작부분에서 툴바 스크립트가 무엇을 알고 있는지 확인하세요.
Re: 일관되지 않은 허용 가능한 구문도구 모음은 스크립트에 Names Default To Here(1)(항상 있어야 한다고 말했듯이)를 추가할 수 있습니다.

그러면 모든 것이 글로벌 범위에 있는 경우 보이지 않는 일부 오류를 잠재적으로 보여줄 수 있습니다(하지만 여전히 일반적으로 오류입니다). 저는 Eval(EvalExpr()) 또는 Eval(Substitute())를 사용하여 수식을 빌드합니다.
Eval(EvalExpr(
newcol = dt << New Column("Temp", numeric, formula(Num(Expr(NameExpr(AsColumn(dt, i))))));
));
대용량 데이터 세트의 경우 이와 같은 것에 대한 샘플링을 고려해야 할 수도 있습니다. 더 빠를 수 있는 비공식 솔루션도 있지만, 데이터에 따라 달라질 수도 있습니다.
어떤 이유에서인지 저는 이것을 JMP 커뮤니티에 게시하지 않았습니다(아니면 적어도 찾을 수 없었을 겁니다), 문자 열에서 숫자로(github.com) , https://github.com/jthi-jmp-tools/character-columns-to-numeric/blob/main/bin/bin/character_columns_to_numeric.jsl 에서 제가 이 작업을 어떻게 수행했는지 코드를 살펴보실 수 있습니다. 그 이후로 이 스크립트를 다시 작성했고 제 기억이 맞다면 요즘은 약간 다른 방법을 사용합니다.
Re: 일관되지 않은 허용 가능한 구문툴바 아이콘은 현재 데이터 테이블을 알고 있습니다():
문제는 오히려 그 반대입니다.
"dt=current data table()"을 정의해 주세요.
dt << Get Column Names();
Re: 일관되지 않은 허용 가능한 구문고마워요 크레이그.
오류 메시지는 다음과 같습니다.
이름 미해결: '2PCS_X(um)'의 액세스 또는 평가에서 행 1에 2PCS_X(um), "2PCS_X(um)"n /*###*/
"2PCS_X(um)"은 평가할 첫 번째 열의 이름입니다.
따라서 첫 번째 열에 대한 표현식은 다음과 같습니다.
newcol = dtTOSA << new column("온도", 숫자, 수식(Num( :"2PCS_X(um)"n )));
Re: 일관되지 않은 허용 가능한 구문또한 실제 스크립트에서는 dt를 변수로 사용하지 않습니다. dtTOSA와 같이 훨씬 더 설명적인 변수를 사용합니다. (위 참조) 특정 데이터 테이블을 언급하고 싶을 때마다 혼란을 피하기 위해 항상 명시적으로 언급합니다. 이 문장에서 한 것처럼요. 통역사가 제가 다른 테이블을 언급하고 있다고 생각할 수 있는 방법이 보이지 않습니다.
Re: 일관되지 않은 허용 가능한 구문아마도 그럴 수도 있지만, 오류 메시지는 JMP가 "2PCS_X(um)"n을 올바른 위치에서 찾지 않는다는 것을 암시합니다. 툴바 스크립트가 어떤 컨텍스트를 사용할 수 있는지 잘 모르겠습니다.
Re: 일관되지 않은 허용 가능한 구문크레이그,
인쇄 명령문을 사용하라는 제안을 사용했는데, 제가 문제라고 생각했던 줄에는 결코 도달하지 못했습니다.
newcol = dt << new column("Temp", numeric, formula(eval(evalexpr(Fexpr))));문제는 바로 이 지점에 있었습니다.
nnm1 = Col Number(colcol);
그래서 이걸 이렇게 바꾸었더니 효과가 있었습니다.
nnm1 = dtTOSA << Col Number(colcol);
코드 후반에 JMP에 현재 테이블이 무엇인지 다시 상기시켜야 했고, 작동하기 전에 Delete Columns에서 {}를 사용해야 했습니다. 어떤 이유에서인지 JMP는 스크립트 창에서 실행하면 중괄호가 있는지 신경 쓰지 않습니다.
코드 조각은 이제 다음과 같습니다. 그런데 이것은 이 테이블과 다른 테이블을 만드는 더 긴 코드의 조각입니다.
AllCols = dtTOSA << Get Column Names();
AllColNames = dtTOSA << Get Column Names(string);
currentDatatable(dtTOSA);
for(i=3, i<=n items(AllCols), i++,
colcol = AllCols[i];
cname = AllColNames[i];
nnm1 = dtTOSA << Col Number(colcol);
Fstr = "num(:\!""||cname||"\!"n)";
Fexpr = parse(Fstr);
newcol = dtTOSA << new column("Temp", numeric, set formula(eval(evalexpr(Fexpr))));
nnm2 = dtTOSA << Col Number(newcol);
if(nnm2 == nnm1,
currentDatatable(dtTOSA);
newcol << delete formula();
dtTOSA << Delete Columns({colcol});
wait(0);
newcol << set name(cname), //else
dtTOSA << Delete Columns({newcol});
);
);하지만 이제 다른 문제가 있습니다. 새 열의 이름을 바꾸기 전에 이전 열을 삭제했는데도 JMP는 열 이름 뒤에 원치 않는 2를 넣습니다! 스크립트 창에서 실행하면 다시 한 번 이렇게 하지 않습니다. wait(0) 문을 포함하려고 했지만 도움이 되지 않았습니다.
이 문제는 어떻게 해결할 수 있나요?
Re: 일관되지 않은 허용 가능한 구문실제로는 열 삭제 작업을 수행하지 않습니다.
dtTOSA << Delete Columns({colcol});즉, 원래 문자 열과 새로운 숫자 열은 유지됩니다.
Re: 일관되지 않은 허용 가능한 구문이상하게도, "else" 조건으로 가면 delete 문이 정상적으로 작동합니다.
Re: 일관되지 않은 허용 가능한 구문열은 2가지 다른 방식으로 참조되지만(하나는 텍스트 문자열 이름으로, 다른 하나는 열 유형으로) 마침내 작동했습니다. 저는 18년 동안 jsl로 코드를 작성해 왔지만 여전히 jsl에서 열을 변수로 참조하는 것이 일관성이 없고 혼란스럽다고 생각합니다.
AllCols = dtTOSA << Get Column Names();
AllColNames = dtTOSA << Get Column Names(string);
currentDatatable(dtTOSA);
for(i=3, i<=n items(AllCols), i++,
colcol = AllCols[i];
cname = AllColNames[i];
nnm1 = dtTOSA << Col Number(colcol);
Fstr = "num(:\!""||cname||"\!"n)";
Fexpr = parse(Fstr);
newcol = dtTOSA << new column("Temp", numeric, set formula(eval(evalexpr(Fexpr))));
nnm2 = dtTOSA << Col Number(newcol);
if(nnm2 == nnm1,
currentDatatable(dtTOSA);
newcol << delete formula();
dtTOSA << Delete Columns(eval(cname));
currentDatatable(dtTOSA);
newcol << set name(cname), //else
dtTOSA << Delete Columns({newcol});
);
);Re: 일관되지 않은 허용 가능한 구문저는 항상 문자열을 열 기반으로 사용한 다음 필요에 따라 문자열에서 참조를 빌드합니다. 이것이 다양한 유형의 참조를 처리하는 가장 유연한 방법이라는 것을 알게 되었습니다.
예를 들어, 귀하의 스크립트를 가져와서 그 목적에 대한 몇 가지 가정을 한다면(세 번째 열부터 시작하여 모든 열을 살펴보고, 값을 숫자로 변경하고, 누락된 값을 비교하고, 결과에 따라 작업을 수행하는 새 수식 열을 만듭니다) JMP18에서 다음과 같이 작성할 것입니다.
Names Default To Here(1);
dtTOSA = New Table("Untitled",
Add Rows(4),
Compress File When Saved(1),
New Column("Column 1",
Numeric,
"Continuous",
Format("Best", 12),
Set Values([1, 2, 3, 4])
),
New Column("Column 2", Character, "Nominal", Set Values({"A", "1", "2", "3"})),
New Column("Column 3", Character, "Nominal", Set Values({"1", "2", "3", "4"})),
New Column("Column 4", Character, "Nominal", Set Values({"A", "B", "C", "D"}))
);
wait(1); // demo purposes
cols = dtTOSA << Get Column Names("String");
// Remove From(cols, 1, 2); // skipping this for demo purposes
For Each({colname}, cols,
// colname = cols[3]; // for testing
Eval(EvalExpr(
newcol = dtTOSA << New Column("Temp", numeric, Formula(
Num(Expr(Name Expr(As Column(dtTOSA, colname))))
));
));
newcol << Run Formulas;
newcol << delete formula();
orig_vals = Col Number(Column(dtTOSA, colname));
new_vals = Col Number(Column(dtTOSA, (newcol << get name)));
If(orig_vals == new_vals,
dtTOSA << Delete Columns(colname);
newcol << set name(colname);
,
dtTOSA << Delete Columns(newcol)
);
);
그리고 만약 내가 처음부터 이것을 하되 여전히 당신이 가지고 있는 것과 비슷한 아이디어를 사용한다면, 나는 (적어도 지금 당장은) 다음과 같은 것을 할 것입니다.
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(4),
Compress File When Saved(1),
New Column("Column 1",
Numeric,
"Continuous",
Format("Best", 12),
Set Values([1, 2, 3, 4])
),
New Column("Column 2", Character, "Nominal", Set Values({"A", "1", "2", "3"})),
New Column("Column 3", Character, "Nominal", Set Values({"1", "2", "3", "4"})),
New Column("Column 4", Character, "Nominal", Set Values({"A", "B", "C", "D"}))
);
wait(1); // demo purposes
cols = dt << Get Column Names("Character", "String"); // We only need to check character columns
For Each({colname}, cols,
dt_summary = dt << Summary(
Group(Eval(colname)),
Freq("None"),
Weight("None"),
Link to original data table(0),
output table name("Summar of " || colname),
Private
);
orig_vals = Col Number(Column(dt_summary, 1));
Column(dt_summary, 1) << Set Data Type("Numeric");
new_vals = Col Number(Column(dt_summary, 1));
Close(dt_summary, no save);
If(orig_vals == new_vals, // we can change
Column(dt, colname) << Set Data Type("Numeric");
Column(dt, colname) << Set Modeling Type("Continuous");
);
);
저는 Transform Each와 Num을 활용하여 이러한 작업을 수행하는 경향이 있지만, 때로는 JMP에서 변환을 수행하도록 하면 충분할 수도 있습니다(이 작업을 수행하고 싶지 않은 경우도 있습니다... 예를 들어, 스크립팅 인덱스에서 Num()을 참조하고 Num("5%")에서 어떻게 동작하는지 확인하세요. << Restrict는 이러한 동작을 방지합니다)
Re: 일관되지 않은 허용 가능한 구문자르모,
생각을 공유해 주셔서 감사합니다. 저는 때때로 수천 개의 열과 수만 개의 행을 가지고 있고, 속도가 문제가 될 수 있습니다. 지금 제가 하는 방식은 실제로 이전에 했던 방식의 약 1/3로 시간을 줄였지만, 여전히 몇 분이 걸릴 수 있습니다. 언젠가 귀하의 방법을 실험해 볼 수는 있지만, 요약 표를 매번 만드는 것이 더 느리거나 더 빠를 것이라고 생각하시는지 궁금합니다.
열 참조 처리와 관련하여 Column(dt, colname)을 사용해 보았지만 항상 작동하지는 않습니다. 하지만 스크립트에서는 As Column()도 사용합니다. 일반적으로 As Column()은 수식에 사용됩니까?
Re: 일관되지 않은 허용 가능한 구문
@pcarroll1 님이 쓰셨습니다:
일반적으로 수식에는 As Column()을 사용합니까?
예, column(columnname) 또는 :column(dt, columnname)[] 으로 가능합니다.
Re: 일관되지 않은 허용 가능한 구문첫 번째 "질문": 특정 사용 사례에 대한 속도를 최적화하려고 하면, 여러 가지 방법이 있고 가장 빠른 방법은 데이터에 따라 크게 달라질 수 있으므로 어떤 방법이 가장 효과적인지 시도해야 합니다. 이 경우 복제 값을 확인하는 것을 피하기 위해 요약 테이블(또는 요약)을 사용했지만, 언급했듯이 데이터, JMP 버전 및 기타 사항에 따라 달라집니다.
열 참조의 경우, 제 규칙은 항상 열 이름과 테이블 참조를 시작점으로 사용하고, 이를 기반으로 최종 참조를 작성하는 것입니다 . 제가 참조 로 간주하는 것은 어디서 어떻게 사용하는지에 따라 달라집니다. 예를 들어, 수식을 작성하는 경우 수식에서 열을 :mycol로 참조하도록 하려고 합니다(AsColumn(mycol) 또는 Column(mycol)[]는 안 됨, 보통 이 두 가지도 괜찮습니다). 그리고 표현식 평가를 사용하여 NameExpr(AsColumn(dt,colname))의 상당히 긴 스타일을 사용하여 :mycol 형식을 가져올 수 있습니다. 일반적으로 AsColumn(dt, colname)(또는 dt:colname)은 Column(dt, colname)[Row()](또는 Column(dt, colname)[])와 동일하며, 이는 현재 행 의 값을 가져옵니다(제 생각 에는 항상 이런 것은 아닙니다. 예를 들어 플랫폼에서 :mycol을 행의 특정 값 대신 참조로 간주합니다...).
예를 들어 mycol이 즉시 평가 되고 초기 Row() 값이 JMP에서 0이기 때문에 누락된 값이 반환됩니다(Row()가 항상 업데이트되므로 수식 내부에서는 문제가 되지 않음)
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
colname = "age";
mycol = NameExpr(AsColumn(dt,colname));
show(mycol)
이것은 JMP에서 열 참조, As Column()(현재 행의 값) 과 Column()(열에 대한 참조) 을 이해하기 가장 어려운 차이점입니다. 이것들이 어떻게 작동하는지 이해하는 것은 매우 어렵습니다... 저는 기본적으로 여러 번 실패하면서 배웠습니다. 그리고 지금은 표현식을 작성할 때 처음에 무엇을 사용해야 할지 잘 알고 있습니다(가끔은 여전히 틀릴 수 있습니다). 이 주제는 제 의견(현재)이 다른 사람들과 다를 수 있고 JMP(JSL) 개발자가 아니더라도 제 자신을 꽤 훌륭한 JMP 스크립터로 생각하기 때문에 언젠가 블로그 게시물을 작성하고 싶은 것입니다.
여기서 한 가지 주의할 점이 있습니다 . 저는 JMP 개발자가 아니고 개발자들이 JSL이 어떻게 작동하는지 생각하는지 신경 쓰지도 않습니다(저는 때때로 개발자들과 의견이 다릅니다). 제 모든 답변은 항상 제가 사용한 JMP 버전에 대한 제 경험에 기반합니다.
이 게시물이 다소 혼란스럽다면 정말 죄송합니다. (오늘 저녁에 맥주를 몇 잔 마셨을 수도 있습니다.:) ). 이 주제에 대한 내 의견에 대해 더 많은 설명을 원하시면 이 주제에 게시할 수 있습니다(하지만 @로 태그를 지정하면 더 쉽게 알아볼 수 있습니다). 필요하면 개인 메시지를 보낼 수도 있습니다.