先日紹介した小技を使って階段グラフをつくる。
例えば機械の台数の推移や在庫・待ち行列など、
どのくらいの長い期間、どんな状態だったのかを知りたいときに階段グラフは役に立つ。
先日の記事で毎日データが残っていない時の対処方法は表現したので、
時系列表現についてはそちらを参考にしてほしい。
前提としてこんなデータがある
ある商品が消費された・購入した、というin out情報と、
その時に取り扱われた量が日付とともに入っている。
一日に何回も消費されたり、購入したりという記録が入っているので、
まず一日ごとに数値を合計してやる必要がある。
もちろん合計するのはin out別々に。
dayの内容はYYYYMMDDになっている。
YYYY-MM-DDであれば時刻変換にかけたらいいが、
この場合は数値として扱うほうが便利。
あとで数値として一致させて処理する。
まずデータ内の日付を並び替える
day <- unique(df$day)
days <- sort(day)
df <- df[order(df$day),]
複数同じ日が入っていたが、daysというデータの中でユニークをとってきた。
これで重複していない日付データが作成できた。
ついでにorderで日付列について並べ替えを行った。
ここは先日の記事を見てもらいたい
ct_seq <- seq(as.POSIXct("2017-11-30","%Y-%m-%d",tz="Japan"),as.POSIXct("2019-08-01","%Y-%m-%d",tz="Japan"),24*60*60)
seq_date <- as.character(ct_seq)
time <- paste0(substr(seq_date,1,4),substr(seq_date,6,7),substr(seq_date,9,10))
購入したものと、消費したもので分け、
日付ごとに合計値を計算する。
in_factor <- df[df$in.out=="in",]
df_bind <- NULL
in_factor_tbl <- NULL
for(q in 1:length(days)){
cal <- in_factor[days[q]==in_factor$day,]
df_bind <- data.frame(day=days[q],val=sum(cal$stoc))
in_factor_tbl <- rbind(in_factor_tbl,df_bind)
}
out_factor <- df[df$in.out=="out",]
df_bind <- NULL
out_factor_tbl <- NULL
for(q in 1:length(days)){
cal <- out_factor[days[q]==out_factor$day,]
df_bind <- data.frame(day=days[q],val=sum(cal$stoc))
out_factor_tbl <- rbind(out_factor_tbl,df_bind)
}
これで各日付についての値を合計したデータが作成できた。
取り扱いの無かった日は0が記入されている。
ただ、もともとの日付には、全く商品に動きが無かった日や、
土日のようにそもそもデータが記入されていない時がある。
これを以下の処理で修正する。
詳しくは先日の記事を参照してほしい。
ind<-c(1:length(seq_date))
plot_label<-data.frame(ind=ind,day=as.numeric(time))
get_ind<-NULL
for(bi in 1:length(day)){
df_bind<-plot_label[plot_label$day==day[bi],]
get_ind<-rbind(get_ind,df_bind)
}
現在の商品在庫数を数えると、
4万個あったとする。
act_stc <- 40000
現在の在庫から、過去のin outを表現していく。
昨日購入したものは、一昨日にはなかったものだから、
現状の在庫から引いていかなければいけない。
昨日消費したものは、一昨日にはあったものだから、
現状の在庫に足してやらなければいけない。
なので、過去にさかのぼるときは、inとoutの考え方を逆にして計算していく必要がある。
in_val <- rev(in_factor_tbl$val)
out_val <- rev(out_factor_tbl$val)
stoc_move <- (in_val*-1) + (out_val)
stoc_trend <- as.numeric(act_stc)
for(cal in 1:length(days)){
stoc_trend <- c(stoc_trend ,stoc_trend[cal] + stoc_move[cal])
}
stoc_trend <- rev(stoc_trend)
stoc_trend <- stoc_trend[-length(stoc_trend)]
get_ind$val <- stoc_trend
ytop <- rep(max(stoc_trend), length(seq_date)-1)
ybot <- c(ytop, min(stoc_trend))
plot(c(1:length(seq_date)), ybot, xaxt="n",type="n",xlab="",main="stoc trend",yaxt='n',ylab="")
axis(side=2,tck=1,lty="dotted",lwd=1)
axis(1,c(1:length(seq_date)), labels=as.character(seq_date),las=2)
axis(2)
これで欠損のある日付を考慮したplotができるようになった。
あとは階段グラフを描くために、segmentを使用して左右上下に線を描きだしてやる。
for(seg in 1:(length(get_ind$ind)-1)){
segments(get_ind$ind[seg], get_ind$val[seg], get_ind$ind[seg+1], get_ind$val[seg])
segments(get_ind$ind[seg+1], get_ind$val[seg+1], get_ind$ind[seg+1] , get_ind$val[seg])
}
これで階段グラフが描けた
以上
可視化大事に。