SUMIF: 列間の条件付き合計を取得するにはどうすればよいですか?<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />10 列の合計を計算して新しい列を作成したいのですが、正の値のみを合計したいと考えています。 同様に、すべての負の値を合計する別の列が必要です。 Excel では、関数 SUMIF: =SUMIF(A1:J1;">0") を使用します。
JMP で同様のことを行うにはどうすればよいですか?
Excel の簡単な例を使用すると (明らかにデータセットの方が大きいですが)、これが私が目指しているものです。
| あ | B | C | D | 正の和 | 負の和 |
| 1,00 | 2,00 | -7,00 | 5,00 | 8,00 | -7,00 |
| 4,00 | 64,00 | 55,90 | 5,20 | 129,10 | 0,00 |
| 86,10 | -34,44 | 5,60 | 7,21 | 98,91 | -34,44 |
| 6,00 | 8,00 | -96,00 | 6,00 | 20,00 | -96,00 |
| 1,00 | -8,00 | 5,00 | 0,64 | 6,64 | -8,00 |
ご協力いただき誠にありがとうございます!
ヤンヌ
Re: SUMIF: 列間の条件付き合計を取得するにはどうすればよいですか?いやぁ、素晴らしいですね!
Re: SUMIF: 列間の条件付き合計を取得するにはどうすればよいですか?私は、上記の Brady の投稿のような、シンプルで賢い列の数式が好きです。 しかし、確かに、テーブルのサイズに応じて大幅に拡張されることがよくあります。
別の方法としては、最初にすべての行の行列全体を取得せずに、列の式で現在の行を直接取得することもできます。 以下の式はそれを試みたものです。
Brady の JSL コードや Ian の明示的な列の合計ほど高速ではありませんが、はるかに高速です。より適切にスケーリングします(ほぼ直線的に)テーブルサイズ付き)、に依存する式よりもdt< 。 10000x4 テーブルの場合、私のラップトップでの実行には約 0.2 秒かかります。
この例では、数式を動的に構築する代わりに、ローカル変数を使用して数式を一般化する別の方法も示しています。できるのはチャレンジ。 (この例では、数式列が常に最後の列のままであると想定されています)。
//テーブルの例
dt =新しいテーブル( 「列間の条件付き合計」 、行の追加( 10000 )) ;
のために(私= 1 、私<= 4 、私++、
dt <<新しい列( "バツ" 、数値、式(ランダム ノーマル( 0 、 1 )))
) ;
dt <<列の削除( 1 ) ;
// すべての列の条件付き合計を加算します
dt <<新しい列( 「ポジティブサム」 、
数値、
式(
地元({私= 0 、 n = Nコル(現在のデータテーブル()) - 1 } 、
和(繰り返す({私++ ;カラム(私)[] * (カラム(私)[] > 0 )} 、 n ))
)
)
) ;
dt <<新しい列( 「マイナスサム」 、
数値、
式(
地元({私= 0 、 n = Nコル(現在のデータテーブル()) - 2 } 、
和(繰り返す({私++ ;カラム(私)[] * (カラム(私)[] < 0 )} 、 n ))
)
)
) ;
Re: SUMIF: 列間の条件付き合計を取得するにはどうすればよいですか?Brady 氏がすでに述べたように、「式」の側面 (新しい行を追加して自動的に結果を取得できる) を省略できれば、行列アプローチの方がはるかに適切に拡張できます。
ただし、数式列を動的に作成したい場合は、次のようになります。
名前デフォルトここへ( 1 ) ;
// 6 つのソース列を持つテーブル
dt =新しいテーブル( 「列の合計」 、
新しい列( 「コラム1」 、数値、 「連続」 、フォーマット( 「12月固定」 、 10 、 3 ) 、式(ランダム ノーマル( 0 、 1 ) ) ) 、
新しい列( 「コラム2」 、数値、 「連続」 、フォーマット( 「12月固定」 、 10 、 3 ) 、式(ランダム ノーマル( 0 、 1 ) ) ) 、
新しい列( 「コラム3」 、数値、 「連続」 、フォーマット( 「12月固定」 、 10 、 3 ) 、式(ランダム ノーマル( 0 、 1 ) ) ) 、
新しい列( 「コラム4」 、数値、 「連続」 、フォーマット( 「12月固定」 、 10 、 3 ) 、式(ランダム ノーマル( 0 、 1 ) ) ) 、
新しい列( 「コラム5」 、数値、 「連続」 、フォーマット( 「12月固定」 、 10 、 3 ) 、式(ランダム ノーマル( 0 、 1 ) ) ) 、
新しい列( 「コラム6」 、数値、 「連続」 、フォーマット( 「12月固定」 、 10 、 3 ) 、式(ランダム ノーマル( 0 、 1 ) ) ) 、
行の追加( 10 )
) ;
// 列のリスト (任意の数の列を指定できます!)
cリスト= dt << getColumnNames ;
// 「負の合計」の数式を作成します
コル投稿=エクスプレッション(コルTBD *もし(コルTBD < 0 、 1 、 0 )) ;
フォーム引数=エクスプレッション(追加()) ;
のために( c = 1 、 c <= Nアイテム( cリスト) 、 c ++、
thisCol投稿=名前式(代わりの(名前式(コル投稿) 、エクスプレッション(コルTBD ) 、 EvalExpr (列として( cリスト[ c ])))) ;
挿入する(フォーム引数、 thisCol投稿) ;
) ;
nsExpr =エクスプレッション(式(未定)) ;
代入( nsExpr 、エクスプレッション(未定) 、名前式(フォーム引数)) ;
// Print(nsExpr);
// 「正の和」の数式を作成します
コル投稿=エクスプレッション(コルTBD *もし(コルTBD >= 0 、 1 、 0 )) ;
フォーム引数=エクスプレッション(追加()) ;
のために( c = 1 、 c <= Nアイテム( cリスト) 、 c ++、
thisCol投稿=名前式(代わりの(名前式(コル投稿) 、エクスプレッション(コルTBD ) 、 EvalExpr (列として( cリスト[ c ])))) ;
挿入する(フォーム引数、 thisCol投稿) ;
) ;
psExpr =エクスプレッション(式(未定)) ;
代入( psExpr 、エクスプレッション(未定) 、名前式(フォーム引数)) ;
// Print(psExpr);
// 2 つの数式列を dt に追加します
nsCol = dt <<新しい列( 「マイナスの合計」 、数値、継続的、フォーマット( 「12月固定」 、 10 、 3 )) ;
makeFormula =エクスプレッション(送信( nsCol )) ;
挿入する( makeFormula 、名前式( nsExpr )) ;
makeFormula ;
psCol = dt <<新しい列( 「プラスの合計」 、数値、継続的、フォーマット( 「12月固定」 、 10 、 3 )) ;
makeFormula =エクスプレッション(送信( psCol )) ;
挿入する( makeFormula 、名前式(p sExpr )) ;
makeFormula ;
Re: SUMIF: 列間の条件付き合計を取得するにはどうすればよいですか?Brady の結果は Ian の結果と一致しますが、次の行を変更する必要があります。メートル= ( dt <<行列として取得)[ 0 、 1 :: 4 】 ;
これに:メートル= ( dt <<行列として取得)[ 0 、 1 :: 3 ] ;
Ian が作成したテーブルには 3 つの列しかありませんが、Brady の例では 4 つの列が含まれています。
Re: SUMIF: 列間の条件付き合計を取得するにはどうすればよいですか?親愛なるイアンとブレイディ、
お二人とも親切かつ迅速な対応をしていただきありがとうございました! 両方のアプローチを試してみましたが、どういうわけか 2 つの異なる結果が得られました:-(。
いくつかの例を手動でテストしたところ、Ian のアプローチでは正しい結果が得られ、Brady のスクリプトでははるかに大きな金額が返されることがわかりました。 理由はわかりません。残念ながら私はまだ JMP 初心者なので、何が問題だったのかわかりません。 しかし、Ian からのアプローチはうまくいきそうなので、私はそのアプローチに固執することにしました (式が 10 列になるとかなり長くなりますが)。
ということで、お二人ともご協力ありがとうございました!!!
(もし 100 列でこれが必要になったら、それまでに JMP に SUMIF 機能が搭載されていることを願いましょう
)
乾杯、
ヤンヌ
Re: SUMIF: 列間の条件付き合計を取得するにはどうすればよいですか?Ian が述べているように、これは多くの列では扱いにくくなる可能性があります。 本当に数式が必要ない (つまり、ソース列が変更されない) 場合は、必要なデータ テーブルを現在の状態で次の JSL を実行することで、すべての行に対して数式をすばやく実行できます (コードでは、数値が列 1 ~ 4 にあると想定しています)。 、コードの 2 行目のインデックスごとに...必要に応じて変更しますが、連続したままにしておきます):
dt =現在のデータテーブル() ;
メートル= ( dt <<行列として取得)[ 0 、 1 :: 4 ] ;
dt <<新しい列( 「ポジティブサム」 、 <<設定値(対サム(エマルト(メートル> 0 、メートル) ` ) ` )) ;
dt <<新しい列( 「マイナスサム」 、 <<設定値(対サム(エマルト(メートル< 0 、メートル) ` ) ` )) ;
数式が必要な場合は、次のコードを使用できます (エディターにコピーして貼り付けるのが最適です)。これは簡単ですが、テーブルが非常に大きくなると、各行の行列全体を取得するため、実行速度が遅くなります。 (負の和の不等式を変更します。
演算子は、上記の Emult() 関数で使用される要素ごとの乗算です。)
dt =現在のデータテーブル() ;
メートル= ( dt <<ゲタスマトリックス)[行() 、索引( 1 、 4 )] ;
和( (メートル> 0 )
メートル) ;
ここでのトレードオフは、パフォーマンスに制限があるにもかかわらず、関数が非常に短く、シンプルであり、さらに列を追加した場合に変更するのが簡単であることです。 ただし、比較的小さなテーブルでのみ使用します。 それ以外の場合は、Ian が提案したようなものを使用するのが最善です。
10,000 行×4 列の乱数テーブルについて説明した 2 つのアプローチを比較します。
スクリプトアプローチ: 0.002713 秒
フォーミュラアプローチ:6.050183秒
スクリプトによるアプローチは、10,000,000 行×4 列のテーブルでわずか 3 秒かかります。 1,000,000 行のテーブルのみで 1 時間後に数式アプローチの実行を中止しました。 結局のところ、式の部分が必要か、それともスクリプトをテーブルに保存して必要に応じて実行するかによって決まります。 そうであれば、パフォーマンスが大幅に向上します。
乾杯、
ブレイディ
Re: SUMIF: 列間の条件付き合計を取得するにはどうすればよいですか?この表のようなアプローチを使用できます。
新しいテーブル( 「列の合計」 、
行の追加( 0 ) 、
新しい列( 「コラム1」 、
数値、
「連続」 、
フォーマット( 「12月固定」 、 10 、 3 ) 、
式(ランダム通常( 0 、 1 ))
) 、
新しい列( 「コラム2」 、
数値、
「連続」 、
フォーマット( 「12月固定」 、 10 、 3 ) 、
式(ランダム通常( 0 、 1 ))
) 、
新しい列( 「コラム3」 、
数値、
「連続」 、
フォーマット( 「12月固定」 、 10 、 3 ) 、
式(ランダム通常( 0 、 1 ))
) 、
新しい列( 「プラスの合計」 、
数値、
「連続」 、
フォーマット( 「12月固定」 、 10 、 3 ) 、
式(
:列 1 *もし( :列 1 >= 0 、 1 、 0 ) + :列 2 *
もし( :列 2 >= 0 、 1 、 0 ) + :列 3 *もし( :列 3 >= 0 、 1 、 0 )
)
) 、
新しい列( 「マイナスの合計」 、
数値、
「連続」 、
フォーマット( 「12月固定」 、 10 、 3 ) 、
式(
:列 1 *もし( :列 1 < 0 、 1 、 0 ) + :列 2 *
もし( :列 2 < 0 、 1 、 0 ) + :列 3 *もし( :列 3 < 0 、 1 、 0 )
)
) 、
行の追加( 10 )
);
列が多い場合、必要な「合計」列をプログラムで作成する方が簡単な場合があります。
Re: SUMIF: 列間の条件付き合計を取得するにはどうすればよいですか?こんにちは、
これは、現在のタスクに非常に役立つスクリプトです。
値が「0/0」の列ではうまく機能します。
dt << 新しい列("合計",数値, 式(
Local({i = 0, n = N Col(現在のデータ テーブル()) - 1},Sum(Repeat({i++ ; (Column(i)[] =="0/0")}, n))) ));
ただし、「some_character」を含む列を編集するにはどうすればよいですか?それらの列をカウントする必要がありますか?
必要な数式を含む最後の列「Sum」を含むデータテーブルを添付しました。
ビッグデータテーブルがあり、特定の値を持つ列をカウントするスクリプトを作成したいと考えています。
ありがとう、
副社長