【App Designer】あ​る区間のデータ数を記​録するアプリの作成に​ついて

MATLAB初心者です。
データ処理用のアプリとして、ある区間のデータ数を記録するアプリの作成を検討しています。
仕様としては、記録の開始と終了のトリガを、値の変化にしたいと考えています。
具体的な内容としては、
下記の図のようなデータを読み込んだ場合、1列目の4行目に0から1(値の変化)となるため記録を開始し、
2列目の10行目に値が5(閾値を任意に設定)になるから記録終了とする。
よって、4行目~10行目の7列分となる(この場合、7という数値が出れば問題ありません。)
となるような計算を行うアプリの作成は可能でしょうか。
素人質問で恐縮ですが、ご教授の程よろしくお願いいたします。

2 Comments

Kojiro Saito
Kojiro Saito on 11 Jan 2022
はい、このような計算を行うアプリは可能ですが、ご質問はApp DesignerでGUIアプリを作らなくてもmスクリプトだけでできてしまう内容になります。
既にGUIアプリでデータを読み込む部分を作成されていますか?
RK
RK on 11 Jan 2022
Edited: RK on 11 Jan 2022
使用環境の都合、アプリでの作成を検討しています。
データを読み込む部分は、下記のコードをコールバックしたボタンで対応予定です。
しかし、肝心の計算部分が手つかずの状態です。
詳しい手順は下記を検討中です。
①ファイルを読み込む(下記のコード)
②開始、及び終了のトリガとなる値を設定(スピナーや手動入力するボックスを用意)
③かかったセル数をボックスに表示(最終的にはセル数×データの分解脳=実際の時間の表示を検討します)
以上、お手数をおかけしますが、アドバイスいただけますと幸いです。よろしくお願いいたします。
[file,path]=uigetfile('*.csv;*.xlsx;*.xls');
[app.data]=readmatrix(fullfile(path,file));

Sign in to comment.

 Accepted Answer

Kojiro Saito
Kojiro Saito on 11 Jan 2022

1 vote

「== 演算子」と関数find の組み合わせで実現できそうです。
スピナーを2つ置いて、StartSpinnerの値が1列目の開始値のトリガー、EndSpinnerの値が2列目の終了値のトリガーになるようにしたサンプル(.mlappファイル)を添付します。

10 Comments

RK
RK on 11 Jan 2022
早急にご対応いただきありがとうございます。
想像していた通りの動作です。
教えていただきたいのですが、上記のコードは、演算子を変更することで、「開始のトリガは(スピナ値)以下のとき」や「(値)以上のとき」に変更可能でしょうか。
また、下記のようなデータで開始のトリガを1、終了のトリガを2とした場合、
該当する区間が2つ出てくると思います。
これらを2つとも抜き出すことも可能なのでしょうか。
度々申し訳ございません。何卒よろしくお願いいたします。
スピナー値以上のときは「==」の演算子を「>=」に、以下のときは「<=」に変更することで可能です。
idx = find(app.data(:, 1) >= app.StartSpinner.Value, 1, 'first') ;
該当する区間が2つ以上ある場合は、色々な方法があると思いますが、
diff 関数を使って行ごとの差分を取って変化分がスピナー値と一致する行を見付け、その行の数だけ列2のスピナー値と一致する行を求め、最後にsum で行数をカウントする方法でできます。
function CalcButtonPushed(app, event)
idx = find(diff(app.data(:, 1)) == app.StartSpinner.Value) + 1;
rows = zeros(1, numel(idx));
for n=1: numel(idx)
rows(1, n) = find(app.data(idx(n):end, 2) == app.EndSpinner.Value, 1, 'first') ; ;
end
app.CalcTime.Value = sum(rows);
end
RK
RK on 11 Jan 2022
ありがとうございます。
diff 関数を使って行ごとの差分を取って変化分がスピナー値と一致する行を見付け」の部分は、
「変化分がスピナー値以上となる行」とすることも可能との理解でよろしいでしょうか。
今回のアプリでは、該当箇所が複数ある場合、それぞれの区間の平均の行数を算出したく存じます。
(こちらも同様に可能でよろしいでしょうか。)
よろしくお願いいたします。
Kojiro Saito
Kojiro Saito on 11 Jan 2022
どちらも可能です。前者は「==」を「>=」にすることでできますし、平均の行数も「sum(rows)」のところを「mean(rows) 」などにすることでできます。
さらにご質問があれば、新たな質問として投稿された方が良いと思います。
RK
RK on 12 Jan 2022
ありがとうございます。
上記、理解できました。
他に質問をする場合は、新たな質問へ投稿いたします。
ご丁寧に対応いただき、ありがとうございました。
RK
RK on 14 Jan 2022
度々申し訳ございません。
上記を実行すると、下記のコードでアラームが発生します。
rows(1, n) = find(app.data(idx(n):end, 2) == app.EndSpinner.Value, 1, 'first') ;
アラーム:左辺のサイズが 1x1 で右辺のサイズが 0x1 であるため、代入を実行できません。
対処可能でしょうか。
お手数をおかけしますが、よろしくお願いいたします。
上記でお示ししたのは正常処理のサンプルなので、異常時のエラーハンドル全てまでは入れておりません。
スピナーで指定した終了トリガーの値がデータの2列目に見つからない場合はこのようなエラーが出ます。
この場合、find の結果が空になるので、isempty を使って判定ができます。下記のようにif isempty で空かどうかチェックを入れて空の場合の処理を追加すれば対応できます。
for n=1: numel(idx)
checkFlag = find(app.data(idx(n):end, 2) == app.EndSpinner.Value, 1, 'first');
if isempty(checkFlag)
checkFlag = 0;
end
rows(1, n) = checkFlag;
end
RK
RK on 14 Jan 2022
ありがとうございます。
度々申し訳ございませんが後1点だけご教示ください。
平均の行数は「sum(rows)」のところを「mean(rows) 」にするだけで対応可能なのでしょうか。
簡単に試しましたが、平均ではなく、最後の該当箇所の行数となってしまいます。
ご確認の程よろしくお願い申し上げます。
rows がベクトルなので、mean は要素の平均値を返します。
例えば rowsが[3 3 4]のとき、平均値は3.333になります。
rows = [3 3 4];
mean(rows)
ans = 3.3333
app.CalcTime.Valueの値も3.333になりますが、もし違っていたら最初の質問からズレてきているので新規質問としたほうが良いと思います。
RK
RK on 14 Jan 2022
ありがとうございます。
承知いたしました。
上記、確認し不明点があれば新規質問といたします。
ご対応いただきありがとうございました。

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB Web App Server in Help Center and File Exchange

Products

Release

R2021a

Asked:

RK
on 7 Jan 2022

Commented:

RK
on 14 Jan 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!