각 행의 마지막 30개 조각 및 기타 데이터 삭제여러분, 안녕하세요,
여러 열이 있는 데이터 테이블이 있고 각 열에는 데이터가 포함된 행 수가 다릅니다. 각 열의 마지막 30행 데이터를 가져오는 방법을 찾으려고 합니다. 예를 들어 열 1에는 50개의 행이 있고 열 2에는 75개의 행이 있으며 각 행에 마지막 30개의 정보 행이 있기를 원합니다. 그렇게 할 수 있는 스크립트가 있나요?
자동화 및 스크립팅데이터 혼합 및 정리대량 맞춤화Re: 각 행의 마지막 30개 조각을 삭제하고 다른 데이터를 삭제합니다.이 트랙의 미래 독자들을 위해 다음 사항을 수정합니다. @마크_베일리 @txnelson 응답의 두 번째 코드 조각과 비교할 때 그의 코드에 대한 설명을 명확히 해야 합니다.일단 결측값이 발견되면 열에 결측값이 아닌 추가 값이 나타나지 않는다고 가정하면 두 코드 조각은 동일한 결과를 생성합니다.@마크_베일리 코드에서는 누락되지 않은 값의 최소 수가 존재해야 하지만 @txnelson 코드는 그렇지 않습니다.
Re: 각 행의 마지막 30개 조각을 삭제하고 다른 데이터를 삭제합니다.FWIW, 행렬을 사용하는 또 다른 버전이 있습니다.
NamesDefaultToHere(1);
// Make a data table 'dt', to play with.
nr = 100; // Number of rows
nc = 30; // Number of columns
p = 0.7; // Proportion of missing values
vals = J(nr*nc, 1, RandomInteger(0, 99));
makeMissing = RandomIndex(nr*nc, Floor(nr*nc*p));
vals[makeMissing] = .;
dt = AsTable(Shape(vals, nr, nc));
dt << setName("Random Integers with some missing");
// Start here with the current table . . .
lastN = 30; // Number of non-missing values to retain
dt = CurrentDataTable();
vals = dt << getAsMatrix;
// Loop over columns . . .
newVals = [];
for(c=1, c<=NCol(vals), c++,
NMV = vals[LocNonMissing(vals[0, c]), c]; // Non-mising values in this column
if(NRow(NMV) >= lastN, // Do we have enough non-missing values?
lastNMV = NMV[(NRow(NMV) - lastN + 1)::NRow(NMV)]; // If so, get the 'lastN' of these . . .
newVals = newVals||lastNMV; // . . . and add them into a new column
);
);
dt2 = AsTable(newVals);
dt2 << setName("Last "||Char(lastN)||" non-missing Random Integers");Re: 각 행의 마지막 30개 조각을 삭제하고 다른 데이터를 삭제합니다.이 버전을 사용해 보세요.
Names Default to Here( 1 );
// create the example
dt = New Table( "Odd Lengths",
New Column( "Column 1", Numeric, Continuous, Values( 1::50 ) ),
New Column( "Column 2", Numeric, Continuous, Values( 1::75 ) ),
New Column( "Column 3", Numeric, Continuous, Values( 1::28 ) )
);
Wait( 0 );
// process the data table
For( col = N Col( dt ), col > 0, col--,
values = Column( dt, col ) << Get Values;
not missing = Sum( Not( Is Missing( values ) ) );
If( not missing < 30,
dt << Delete Columns( Column( dt, col ) ),
end = Contains( values, . ) - 1;
If( end == -1, end = N Row( dt ) );
view = end - 29 :: end;
Column( dt, col ) << Set Values( values[view] );
);
);
dt << Select Where( Row() > 30 ) << Delete Rows;
Re: 각 행의 마지막 30개 조각을 삭제하고 다른 데이터를 삭제합니다.@마크_베일리 이것은 훌륭하게 작동합니다! 30보다 작고 30보다 큰 열에 데이터가 있다는 것을 깨달았습니다. 이를 표시하는 쉬운 방법이 있습니까? 예 열 1에는 50개의 행이 있고 열 2에는 75개의 행이 있고 열 3에는 28개의 행이 있으며 각 행에는 마지막 30개 행의 정보가 30개 미만인 정보가 없도록 하려고 합니다. 따라서 데이터 포인트가 29개 이하인 경우 삭제하고 싶습니다. 또한. 도와 주셔서 감사합니다!
Re: 각 행의 마지막 30개 조각을 삭제하고 다른 데이터를 삭제합니다.다음은 두 번째 솔루션과 동일한 결과를 달성하는 또 다른 버전입니다. @txnelson
For( col = 1, col <= N Col( dt ), col++,
values = Column( dt, col ) << Get Values;
end = Contains( values, . ) - 1;
If( end == -1, end = N Row( dt ) );
view = end - 29 :: end;
Column( dt, col ) << Set Values( values[view] );
);
dt << Select Where( Row() > 30 ) << Delete Rows;
Re: 각 행의 마지막 30개 조각을 삭제하고 다른 데이터를 삭제합니다.데이터 테이블의 마지막 30개 행을 제외하고 모두 삭제하는 것은 쉽습니다.
Names Default To Here( 1 );
dt = Current Data Table();
dt << select where( Row() > N Rows( dt ) - 30 );
dt << delete rows;
각 열에 대해 마지막 30개의 누락되지 않은 데이터 포인트를 찾고 이를 n열 x 30행 데이터로 저장하도록 요청하는 경우 이는 조금 더 어렵고 그렇게 하는 것이 타당성 있는지 의문을 제기할 것입니다.그 결과 서로 다른 열 사이의 데이터 포인트 간의 관계가 거의 제거됩니다.
Names Default To Here( 1 );
dt = Current Data Table();
// Copy the data table retaining no rows;
dtCopy = dt << subset( selected rows( 0 ), selected columns( 0 ) );
dtCopy << select where( Row() >= 0 );
dtCopy << delete rows;
For( i = 1, i <= N Cols( dtCopy ), i++,
theList = {};
For( k = N Rows( dt ), k >= 1, k--,
If( Is Missing( Column( dt, i )[k] ) == 0,
Insert Into( theList, Column( dt, i )[k] );
If( N Items( theList ) >= 30,
Break()
);
)
);
Column( dtCopy, i ) << set values( Reverse( theList ) );
);