줄에서 열 이름으로 단어를 추출하고 해당 숫자를 열에 값으로 추출다양한 장치에서 추출된 오류 코드가 있는 "결함"이라는 열이 있습니다. 특정 날짜의 오류 코드 중 하나가 아래에 나와 있습니다.
"인버터 인버터 20 제한 미만: 0.96KW/인버터(1.63KW의 58.9%) at 11/30/2019 7:30:00 AM(sun az: 123.4 el: 3.7) 기간: 4.00시간 인버터 인버터 23 제한 미만: 0.95 킬로와트/인버터(1.63킬로와트의 57.9%) at 11/30/2019 7:30:00 AM (sun az: 123.4 el: 3.7) 기간: 3.50시간"
목표는 분석을 수행하여 결함이 있는 인버터를 날짜와 누적 성능 및 기간별로 표로 만드는 것입니다. 나중에 다른 값을 사용하여 결함을 진단합니다.
----열 이름: 값 형식으로 다음과 같이 세부 정보를 추출해야 합니다.
인버터: 20
한계치 이하(kW/인버터) : 0.96
최대 %: 58.9%
날짜 2019년 11월 30일
시간 : 오전 7시 30분
선아즈 : 123.4
표고:3.7
기간(시간) : 4
오류 코드가 있는 두 번째 인버터가 있는 경우(위 오류 코드의 두 번째 줄 참조)
인버터: 23
한계치 이하(kW/인버터) : 0.95
최대 %: 57.9%
날짜 2019년 11월 30일
시간 : 오전 7:30:00
선아즈 : 123.4
표고:3.7
기간(시간) : 3.50
때로는 한 줄에 유사한 코드를 제공할 수 있는 5개 또는 10개의 인버터(70개 중)가 있을 수 있습니다.
이 작업을 수행하는 방법을 알려주실 수 있습니까? JSL을 통해서만 가능합니까? 아니면 수식을 사용할 수 있습니까? 어느 쪽이든 도움이 필요합니다.
고급 통계 모델링자동화 및 스크립팅소비자 및 시장 조사대량 맞춤화품질 및 프로세스 엔지니어링Re: 행에서 열 이름으로 단어를 추출하고 열에 값으로 해당 숫자를 추출합니다.안녕 써니R,
나는 이것이 오래된 게시물이라는 것을 알고 있지만 문제가 흥미롭다는 것을 알았고 당신과 비슷한 상황에서 가끔 사용하는 아이디어를 공유하고 싶었습니다. 데이터가 잘 구조화되고 너무 복잡하지 않은 경우 매우 강력하고 간단합니다.
참고: 이 특정 솔루션은 로그가 현재 테이블의 유일한 데이터 열인 단일 데이터 열에 있다고 가정합니다. 언급했듯이 다른 행에는 다른 수의 인버터 로그가 포함될 수 있습니다.
"hours"라는 단어는 각 인버터의 로그 끝에만 나타나므로 이러한 방식으로 로그 기록을 깨고 데이터를 쌓을 수 있습니다. 완료되면 숫자를 유지하기 위해 텍스트를 분할합니다. 모든 로그에는 항상 같은 순서로 동일한 텍스트와 측정값이 있어야 합니다. 따라서 텍스트를 구분할 때 열에 정렬됩니다.
모든 열을 숫자로 변환하여 숫자가 아닌 데이터를 명확하게 만듭니다. 즉, 누락됩니다. 숫자가 아닌 데이터를 삭제하고 열의 이름을 바꾸면 완료됩니다.
이것이 어떻게 작동하는지 볼 수 있도록 테이블 스크립트가 있는 테이블을 첨부했습니다.
Names Default To Here( 1 );
dt = :log << get data table; // for use within a table script. otherwise, use dt = current data table();
// can break up the logs at "hours". Replace with ~ or some other unused character to delimit.
For( i = 1, i <= N Row( dt ), i++,
dt:log[i] = Substitute( dt:log[i], "hours", "~" )
);
//split the logs using this delimiter
dt << Text to Columns( delimiters( "~" ), columns( :log ) );
// some logs had more inverters than others, so the stack my have empty data in some rows. Delete them.
dt2 = dt << stack( columns( (dt << get column names)[2 :: N Col( dt )] ) );
dt2 << delete rows(dt2 << get rows where (:data == ""));
//using parens and spaces as delimiters, break up each log
dt2 << text to columns( delimiters( " ()" ), columns( :data ) );
//deal with date and time. They're always in the same columns, making this easier
dt2 << New Column( "date", formula( Informat( :data 14 ) ) );
dt2 << New Column( "time", formula( Informat( :data 15 || " " || :data 16 ) ) );
dt2:date << Delete Formula;
dt2:time << Delete Formula;
dt2 << delete columns( {"data 14", "data 15"} ); //else these persist later, as they are numeric
//Remove non-numeric columns by changing all columns to numeric and removing those containing only missing data.
//Proceed "backward" as deletions change indices.
For( i = N Col( dt2 ), i >= 1, i--,
Column( dt2, i ) << set data type( numeric );
If( N Row( Loc( dt2:i << get values ) ) == 0, dt2 << delete columns( i ) );
);
//rename columns and reformat date and time.
colNames = Words( "Inverter,Below Limit(kw/inverter),% of max,Max,Sun Az,Elevation,Duration", "," );
For( i = 1, i <= N Items( colNames ), i++, Column( dt2, i ) << set name( colNames[i] ) );
dt2:date << Format( "m/d/y" );
dt2:time << Format( "h:m:s" );Re: 행에서 열 이름으로 단어를 추출하고 열에 값으로 해당 숫자를 추출합니다.놀라운! 작동합니다. 내 요청을 수행하기 위해 이 긴 코드를 작성하는 동안 기다려 주셔서 감사합니다. 내가 가지고 있는 다른 경고 코드에 이것을 구현하려고 합니다. 정말 감사합니다. 영겁의 시간을 절약했습니다.
Re: 행에서 열 이름으로 단어를 추출하고 열에 값으로 해당 숫자를 추출합니다.나는 약간의 여유 시간이 있었습니다......Covid-19와 관련하여 아직 할 일이 별로 없었기 때문에 데이터를 읽을 때 좋은 시작을 제공할 약간의 JSL을 작성했습니다.
Names Default To Here( 1 );
dt = Open(
"Path to the data file",
columns( New Column( "c000001", Character, "Nominal" ) ),
Import Settings(
End Of Line( CRLF, CR, LF ),
End Of Field( CSV( 0 ) ),
Strip Quotes( 1 ),
Use Apostrophe as Quotation Mark( 0 ),
Use Regional Settings( 0 ),
Scan Whole File( 1 ),
Treat empty columns as numeric( 0 ),
CompressNumericColumns( 0 ),
CompressCharacterColumns( 0 ),
CompressAllowListCheck( 0 ),
Labels( 0 ),
Column Names Start( 1 ),
Data Starts( 1 ),
Lines To Read( "All" ),
Year Rule( "20xx" )
)
);
// Create the new output data table
dtLong = New Table( "Long Data",
New Column( "Label", character ),
New Column( "Value", character ),
New Column( "Line" ),
New Column( "Instance" )
);
// A function that returns the next word in the line and
// then removes the word from the front of the target line
getWord = Function( {},
theWord = Trim( Word( 1, target, " " ) );
target = Trim( Substr( target, Length( theWord ) + 1 ) );
theWord;
);
// Loop through all rows in the input data table
For( i = 1, i <= N Rows( dt ), i++,
instance = 0;
target = Column( dt, 1 )[i];
While( Word( 1, target, " " ) != "",
dtLong << add rows( 1 );
dtLong:line[N Rows( dtLong )] = i;
theWord = getWord();
Match( theWord,
"inverter",
instance++;
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:Label[N Rows( dtLong )] = theWord;
theWord = getWord();
theWord = getword();
dtLong:value[N Rows( dtLong )] = theWord;,
"below",
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:Label[N Rows( dtLong )] = theWord || " limit (KW/Inverter)";
theWord = getWord();
theWord = getWord();
dtLong:value[N Rows( dtLong )] = theWord;
// Get the % of Max
dtLong << Add Rows( 1 );
dtLong:line[N Rows( dtLong )] = i;
dtLong:Instance[N Rows( dtLong )] = instance;
theWord = getWord();
theWord = getWord();
dtLong:Label[N Rows( dtLong )] = "% of Max";
dtLong:value[N Rows( dtLong )] = Substr( theWord, 2 );
// Skip forward to the Date
For( k = 1, k <= 5, k++,
theWord = getWord()
);
// Get the Date
dtLong << add rows( 1 );
theWord = getWord();
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:line[N Rows( dtLong )] = i;
dtLong:Label[N Rows( dtLong )] = "Date";
dtLong:value[N Rows( dtLong )] = theWord;
// Get the Time
dtLong << add rows( 1 );
theWord = getWord();
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:line[N Rows( dtLong )] = i;
dtLong:Label[N Rows( dtLong )] = "Time";
dtLong:value[N Rows( dtLong )] = theWord || getWord();
// Get the Sun Az
dtLong << add rows( 1 );
theWord = getWord();
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:line[N Rows( dtLong )] = i;
dtLong:Label[N Rows( dtLong )] = Substr( theWord, 2 ) || " " || getWord();
dtLong:value[N Rows( dtLong )] = getWord();
// Get the Elevation
dtLong << add rows( 1 );
theWord = getWord();
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:line[N Rows( dtLong )] = i;
dtLong:Label[N Rows( dtLong )] = "Elevation";
dtLong:value[N Rows( dtLong )] = Word( -1, getWord(), ")" );,
"Duration:",
dtLong:Instance[N Rows( dtLong )] = instance;
dtLong:Label[N Rows( dtLong )] = theWord || " (hrs)";
dtLong:value[N Rows( dtLong )] = getWord();
theWord = getWord();
)
;
);
);Re: 행에서 열 이름으로 단어를 추출하고 열에 값으로 해당 숫자를 추출합니다.짐
제안해 주셔서 감사합니다. 노력하겠습니다. 저는 스크립팅이 처음이므로 이해하기 위해 예제를 살펴보겠습니다.
Re: 행에서 열 이름으로 단어를 추출하고 열에 값으로 해당 숫자를 추출합니다.이와 같은 데이터를 여러 번 처리해야 했습니다.제 생각에 취해야 할 접근 방식은 입력 파일의 모든 데이터를 JMP 데이터 테이블로 읽어들이는 것입니다. 여기서 각 전체 행은 단일 열로 읽혀집니다.하나의 열과 입력 데이터 테이블의 행 수와 동일한 행 수가 있는 데이터 테이블이 생성됩니다.
다음으로 레이블, 값 및 라인의 3개 열이 있는 새 테이블을 만듭니다.그런 다음 하나의 열에 있는 각 행의 내용을 스캔하는 JSL을 사용하여 새 테이블에 새 행을 만들고 레이블(예: 인버터, 제한 미만(KW/인버터) 등), 값(예: 20 , 0.96 등) 및 현재 행 번호인 Line.....Row().라인의 첫 번째 인버터 또는 두 번째 인버터 등을 기반으로 하는 추가 출력 열이 있어야 할 수도 있습니다.
구분 기호로 ":"을 검색하는 Word() 함수와 While() 함수를 함께 사용하면 됩니다.홀수 단어는 레이블이고 짝수 단어는 값입니다.
이 새 테이블이 생성되면 Tables=>Split을 사용하여 인버터당 한 행으로 쉽게 이동할 수 있습니다.
Re: 행에서 열 이름으로 단어를 추출하고 열에 값으로 해당 숫자를 추출합니다.데이브,
예, 결함이 있는 인버터가 1~2개만 있는 경우 가능합니다. 하지만 예를 들어 단일 날짜에 대해 한 줄에 23개의 오류 코드가 있는 경우 개별적으로 너무 많은 열을 만든 다음 각각에 대한 공식을 작성해야 합니다. 23개의 인버터. 귀하의 솔루션을 이해하고 있는지 명확히 할 수 있습니까?또한 추출 후 분석의 목표를 요약하는 또 다른 라인을 추가했습니다.
Re: 행에서 열 이름으로 단어를 추출하고 열에 값으로 해당 숫자를 추출합니다.수식 편집기를 사용하여 이것에 대해 많은 진전을 이룰 수 있어야 합니다. WORD 함수를 살펴보십시오.