【App designer】あ​る区間のデータ数を測​定し、データ数の平均​を出すアプリの作成に​ついて

13 views (last 30 days)
RK
RK on 14 Jan 2022
Commented: RK on 18 Jan 2022
App designerにて、下記のアプリを作成していますが、上手くいきません。
アプリの詳細は下記の通りです。
<内容>
①データファイル(プログラム中 app.data)を読み込み
②データの1列目において、値が1以上立ち上がる前の位置から、
 データの2列目において、値が1以上になる位置までの行数を計算
③データの全てにおいて、②を行い、平均の行数(プログラム中 ans)を算出
そこで、下記のプログラムを作成しました。
df = diff(app.data(:, 1));
idx = find(df >= 1, 1, 'first') ;
rows = zeros(1, numel(idx));
for n=1: numel(idx)
checkFlag = find(app.data(idx:end, 2) >= 1, 1, 'first') ;
if isempty(checkFlag)
checkFlag = 0;
end
rows(1, n) = checkFlag;
end
ans = mean(rows);
下記のようなデータを読み込み、結果としては赤枠で囲った部分の行数の平均(4+9)/2=6.5と出て欲しいのですが、4と算出されます。
不等号の処理が怪しいと思うのですが、解決できません。
修正点があればご教授いただけますと幸いです。
何卒よろしくお願いいたします。

Accepted Answer

Atsushi Ueno
Atsushi Ueno on 17 Jan 2022
前回の回答のコメントを踏まえ、for文を使った方で回答します。
質問に提示されたプログラムの問題点は、find関数の2番目の引数(n — 検出する非ゼロの数)を1にしている事です。
idxはスカラ値になりfor n=1:numel(idx)としても1回しか実行されません。従って上記引数を1からinfに変更しました。
もう一つのfind関数は2番目の引数を1とし1つのみ抽出します。idxの値は複数ある可能性があるのでn番目の数値を使います。
app.data = [0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1; 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1]';
df = diff(app.data(:, 1));
idx = find(df >= 1, inf, 'first'); % 2番目の引数(n — 検出する非ゼロの数)を1からinfに変更
rows = zeros(1, numel(idx));
for n = 1:numel(idx)
checkFlag = find(app.data(idx(n):end, 2) >= 1, 1, 'first'); % こちらは1のまま
if isempty(checkFlag)
checkFlag = 0;
end
rows(1, n) = checkFlag;
end
ans = mean(rows)
ans = 6.5000
  1 Comment
RK
RK on 18 Jan 2022
ありがとうございます。
上記の場合であれば、size(rows(:))により、回数の導出も可能でしょうか。
問題がある場合、別途新たな質問として作成いたします。
よろしくお願いいたします。

Sign in to comment.

More Answers (1)

Atsushi Ueno
Atsushi Ueno on 14 Jan 2022
【プログラム例】
app.data = [0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1; 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1]';
idx = find(diff(app.data(:, 1)) >= 1, inf, 'first'); % 2番目の引数nを1からinfに変更
checkFlag = find(app.data(:, 2) >= 1, inf, 'first'); % 2番目の引数nを1からinfに変更
distance = checkFlag - idx';
distance(distance < 0) = inf;
rows = min(distance) + 1;
ans = mean(rows)
ans = 6.5000
【解説】
質問に提示されたプログラムの問題点は、find関数の2番目の引数(n — 検出する非ゼロの数)を1にしている事です。
idxはスカラ値になりfor n=1:numel(idx)としても1回しか実行されません。従って上記引数を1からinfに変更しました。
またMATLABなのでfor文は使わない方向でプログラムを変更しました。
app.data = [0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1; 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1]';
app.data % ①データファイル(プログラム中 app.data)を読み込み
ans = 16×2
0 0 0 0 1 0 1 0 1 1 0 1 0 1 0 0 1 0 1 0
% ②データの1列目において、値が1以上立ち上がる前の位置、③データの全てにおいて、②を行う
idx = find(diff(app.data(:, 1)) >= 1, inf, 'first') % 2番目の引数nを1からinfに変更
idx = 2×1
2 8
% ②データの2列目において、値が1以上になる位置、③データの全てにおいて、②を行う
checkFlag = find(app.data(:, 2) >= 1, inf, 'first') % 2番目の引数nを1からinfに変更
checkFlag = 4×1
5 6 7 16
distance = checkFlag - idx' % ここで①と②の相対距離を演算する
distance = 4×2
3 -3 4 -2 5 -1 14 8
distance(distance < 0) = inf % 負の値は逆方向なのでinfに変更し取り扱わない
distance = 4×2
3 Inf 4 Inf 5 Inf 14 8
rows = min(distance) + 1 % 最も近い距離(赤枠で囲った部分の行数)を選択する
rows = 1×2
4 9
ans = mean(rows) % 距離の平均値を演算する
ans = 6.5000
  3 Comments
Atsushi Ueno
Atsushi Ueno on 17 Jan 2022
①MATLABでfor文が好ましくない理由
for文も良いです。適材適所だと思います。
②赤枠内の平均値に加え、赤枠自体(該当箇所)の回数の導出も可能でしょうか。
size(rows(:))で導出できると思いましたが、私の仕様解釈に穴がある事に気付きました。データの1列目において値が1以上立ち上がる前の位置から、データの2列目において値が1以上になる位置までの間に、データの1列目において値が1以上立ち上がる箇所がもう一度出現した時にもそれを1区間として重複してカウントしてしまいます。
RK
RK on 18 Jan 2022
上記、回答いただききありがとうございます。
承知いたしました。

Sign in to comment.

Categories

Find more on App Designer を使用したアプリ開発 in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!