Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
まさに昨今、話題の集計なのですが・・・
お知恵を貸してください。簡単なような計算なのに手こずってます。
同じ時間帯(分刻み)で一緒に部屋にいた人数を計算したいのです。
下記が入室テーブルになります。
name stime etime
A 10:00 10:10
B 10:09 10:12
C 10:13 10:13
それを下表のように集計したいのですがIntervalMatch?の使い方等
教えて頂ければ幸いです。
時間帯 人数
10:00 1 (Aさんのみだから)
10:01 1
10:02 1
10:03 1
10:04 1
10:05 1
10:06 1
10:07 1
10:08 1
10:09 2 (AさんとBさんだから)
10:10 2
10:11 1 (Bさんのみだから)
10:12 1
10:13 1 (Cさんのみだから)
お手数かけますがよろしくお願い致します。
おそらくですが、その時間の人数だけでなく誰が居たかも管理したいと思いますので、以下のようなテーブルを作成できれば良いのかと。
Time,Name
10:08,A
10:09,A
10:09,B
10:10,A
10:10,B
10:11,B
サンプルドキュメントを作ってみました。
やはり、IntervalMatch関数の問題ではなく、少数値を利用した計算による誤処理でした。
添付ファイルのように、一旦少数値の時刻情報を整数に変更して処理を行い、最後に時刻情報に戻すときれいに処理が行えました。
少しややこしいですが、参考にしてみて下さい。
※1箇所書式指定が漏れていましたので、ファイル差し換えました。(17:44)
ドキュメントを添付しました。
※先に投稿したドキュメントにて、ループで使っている関数を間違えていました。失礼しました。
誤:NoOfFields() → 正:NoOfRows()
・10:05:30に入室 → 10:06:05に退室 という人は、10:05と10:06の2分間でカウントする
ということがしたい気がするので、「Duration」のフィールドは使わずに入退出時間だけで実装しました。
日付をまたいでも動作すると思っていますが、実際のデータを見てご確認ください。時間のフォーマット(2020/03/04 09:58:05なのか、2020/3/4 9:58:05なのか、)でも動きが変わるかもしれません。
なお、現実の生データを扱うと、「退室時間が無い」「入室してるはずの人がもう一度入室する」ということがあったりすると思いますので、必要に応じて例外処理を追加したり、元データのクレンジングをしてください。
おそらくですが、その時間の人数だけでなく誰が居たかも管理したいと思いますので、以下のようなテーブルを作成できれば良いのかと。
Time,Name
10:08,A
10:09,A
10:09,B
10:10,A
10:10,B
10:11,B
サンプルドキュメントを作ってみました。
凄すぎて、何がなんだか・・・ ド素人の理解を超えてます(泣)
もしStime etimeが下記の仕様だったら、どうなるでしょうか?厚かましくてごめんなさい
//入退室データ
sample:
LOAD * INLINE [
name,stime,etime
A,2020/03/03 10:00,2020/03/03 10:10
B,2020/03/03 10:09,2020/03/03 10:12
C,2020/03/03 10:13,2020/03/03 10:13
];
取り扱うデータが、時間 → 日付に代わるので、使用する関数もTime()/Time#関数 → Date()/Date#関数にすれば動くと思います。ドキュメント添付しておきました。
なお、最後のLoad分にて、text()関数を使っている部分があります。
>Text(Date(Date#( ~~~ as time_in,
今回の事例に限った話では無いですが、日付関数を使った際、見た目は同じだけど違う値として取り込まれることがよくあります。(Text()を外すと、Aさんの10:10とBさんの10:10が別物として扱われます。内部値の問題?)
とりあえずこう記述しておけば動くようですが、正しい対処方法がわかりません。
質問に便乗するようで申し訳ありませんが、どなたか知っている人がいたら教えて下さい。
(今後、自社でも入室管理するかもしれませんので、もっとスマートなやり方があればぜひ教えて下さい!)
>Text(Date(Date#( ~~~ as time_in,
見た目は確かに同じでも、隠れている秒とかの内部値が違うから一緒にならずグラフとか書いても同じのが並びますよね。text使って同じ値に強制的にしないといけないその辺はわかるのですが、変数使ってぶん回すところが、いまひとつ私の能力を超えていて。。。
LOADインラインの部分を実際のCSVとかロードした場合、
Autogenerate: generate count is out of range
Data:
LOAD
Text(Date(Date#('17:46', 'YYYYMMDD hh:mm') + Date#(recNo()-1,'m'),'YYYYMMDD hh:mm')) as time_in,
'Aさん' as name_in
AutoGenerate
とかなってしまって、さらにぱにくっております(汗)
IntervalMatchを使う場合は、添付のような記述でいけます。
注意が必要な点として、IntervalMatch利用時に、etimeをそのまま利用すると対応しない時刻(time_in)が発生するケースが存在しました。(nameがBとCの時)
おそらくIntervalMatch関数の問題ではなく、少数である時刻情報を利用している事に起因する計算時の誤算だと思います。(コンピューターの小数計算は誤差が生じるケースがあります。)
サンプルファイルでエンド側の時刻に1秒足す事で解決していますが、このあたりはもう少し調べる予定です。
Kuya_japanさんが記載されていた見た目が同じでも日付がひもづかない件に関しては、片方がテキストで、片方が数値(シリアル値)によるものです。
その他、見た目上では'2020/3/1'となっていても、実際には'2020/03/01 1:23'などといった状態で、シリアル値にすると値が違うケースもあります。
この場合は、floor関数を使って、少数以下を切り捨てれば大丈夫です。
通常日付はシリアル値で取得している方が使いやすいと思うので、Data関数を使って書式を指定してあげた方が使いやすいとは思います。
やはり、IntervalMatch関数の問題ではなく、少数値を利用した計算による誤処理でした。
添付ファイルのように、一旦少数値の時刻情報を整数に変更して処理を行い、最後に時刻情報に戻すときれいに処理が行えました。
少しややこしいですが、参考にしてみて下さい。
※1箇所書式指定が漏れていましたので、ファイル差し換えました。(17:44)
有難うございました!
ロードスクリプトのデバッグモードを使い、「ステップ」を押しながら少しずつ進めてみてください。おそらくですが、変数の設定を行う際に滞在時間(分)の取得がうまくいっていないと思います。
ロードしたCSVのデータの時間は「17:46」になっていますか?「2020/03/03 17:46」になっていますか?
>Text(Date(Date#('17:46', 'YYYYMMDD hh:mm') + Date#(recNo()-1,'m'),'YYYYMMDD hh:mm')) as time_in,
↑の記述を見るに、CSVの時間データは「17:46」になっているか、「2020/03/03」と「17:46」のフィールドが分かれていると思います。もし可能であれば、CSVのサンプルを提供してください。
※データ自体は適当にマスクして下さい。レコード件数も数件で構いません。
KentaroWakamatsu さん
ありがとうございます。
おっしゃる通り、一旦無理やり整数にしてから日付に置きなおしたり、
一度テキストに置き換えた後に改めて日付に置き換えたりすることで回避できることは確認しています。
Date(Date#(text([加工した日付データ]),'YYYY/MM/DD'), 'YYYY/MM/DD') など。
正直、極端にパフォーマンス劣化しなければ動けばなんでもいいと思っていますが、、、
本筋からそれてしまうので、この件は改めて(いつの日か)投稿しようと思います。お騒がせしました。
お忙しい中、お返事くださり誠にありがとうございます。
サンプルのデータを置かせて頂きます。(先ほどのエラーメッセージの投稿時のデータと違います)
お時間あるときで結構ですので宜しくお願い申し上げます。
日付をまたぐ入室 退室もあります・・・ すみません(汗