各行の最後の 30 個を抽出し、他のデータを削除しますこんにちは、みんな、
複数の列を含むデータテーブルがあり、各列にはデータが含まれる行の数が異なります。 各列のデータの最後の 30 行を取得する方法を見つけようとしています。 たとえば、列 1 には 50 行、列 2 には 75 行があり、各行に最後の 30 行の情報が含まれるようにしたいとします。 それができるスクリプトはありますか?
自動化とスクリプト作成データのブレンディングとクリーンアップマスカスタマイゼーションRe: 各行の最後の30個を取得し、他のデータを削除しますこのトラックを将来読む人のために、 @Mark_Bailey @txnelson の応答からの 2 番目のコードと比較したときの彼のコードに関するステートメントを明確にする必要があります。欠損値が見つかると、その列には欠損以外の値が追加で表示されないと仮定すると、2 つのコードは同じ結果を生成します。@Mark_Baileyコードでは、最小数の非欠損値が存在する必要がありますが、@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個を取得し、他のデータを削除します@Mark_Baileyこれはうまくいきます! 列に 30 未満と 30 を超えるデータがあることに気づきました。これだけを表示する簡単な方法はありますか? 例列 1 には 50 行、列 2 には 75 行、列 3 には 28 行があり、各行の最後の 30 行には 30 未満の情報がないようにしたいので、29 以下のデータポイントがある場合は削除したいと思います。また。 助けてくれてありがとう!
Re: 各行の最後の30個を取得し、他のデータを削除しますこれは、 の 2 番目のソリューションと同じ結果を達成するための別のバージョンです。 @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 列×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 ) );
);