良いニュースは、私があなたへの答えを持っているということです。悪いニュースは、あなたが自問すべき質問が他にもあるということです. まず悪いニュース: 'c' のゼロ以外の値が同数ある複数の日をどのように扱うかを検討する必要があります。この回答では、それについては触れません。
ここで朗報です。これは非常に簡単です。
ステップ 1 : まず、データ フレームを再フォーマットしましょう。いくつかの変数のデータ型を変更しているため (b を datetime に、c を数値に)、新しいデータ フレームを作成するか、古いデータ フレームを再調整する必要があります。次のように、オリジナルを保存して新しいものを作成することを好みます。
a <- df1$a
b <- strptime(df1$b, "%d/%m/%Y %H:%M")
c <- as.numeric(df1$c)
hour <- as.numeric(format(b, "%H"))
date <- format(b, "%x")
df2 <- data.frame(a, b, c, hour, date)
# a b c hour date
# 1 1 2012-12-05 05:00:00 0 5 12/5/2012
# 2 2 2012-12-05 06:00:00 0 6 12/5/2012
# 3 3 2012-12-06 05:00:00 0 5 12/6/2012
# 4 4 2012-12-06 06:00:00 1 6 12/6/2012
# 5 5 2012-12-07 09:00:00 1 9 12/7/2012
# 6 6 2012-12-07 07:00:00 1 7 12/7/2012
「時間」変数と「日付」変数も追加したことに注意してください。これは、後の集計関数のために、これらのフィールドでデータを簡単にソートできるようにするためです。
ステップ 2 : では、毎日 06:00 から 08:00 までの間にゼロ以外の値がいくつあるかを計算してみましょう。「時間」の値を使用しているため、これは「6」と「7」の値を意味します (06:00 ~ 07:59 を表します)。
library(plyr)
df2 <- ddply(df2[df2$hour %in% 6:7,], .(date), mutate, non_zero=sum(c))
# a b c hour date non_zero
# 1 2 2012-12-05 06:00:00 0 6 12/5/2012 0
# 2 4 2012-12-06 06:00:00 1 6 12/6/2012 1
# 3 6 2012-12-07 07:00:00 1 7 12/7/2012 1
'plyr' パッケージは、このようなものに最適です。「ddply」パッケージは具体的にはデータ フレームを入力と出力の両方として受け取り (したがって「dd」)、「mutate」機能を使用すると、追加の列を追加しながらすべてのデータを保持できます。この場合、 の各日の 'c' の合計が必要です.(date)
。時間によるデータのサブセット化は、 data 引数df2[df2$hour %in% 6:7,]
で処理されます。これは、時間の値がセット {6,7} にある行を表示するように指示します。
ステップ 3 : 最後のステップは、ゼロ以外の値の最大数によってデータをサブセット化することです。使用した余分な列を削除して、元の 3 つに戻すことができます。
subset_df <- df2[df2$non_zero==max(df2$non_zero),1:3]
# a b c
# 2 4 2012-12-06 06:00:00 1
# 3 6 2012-12-07 07:00:00 1
幸運を!
更新: OP の要求で、プロット用の時間列も含む新しい「ddply」関数を作成しています。
df2 <- ddply(df2[df2$hour %in% 6:7,], .(date), mutate, non_zero=sum(c), plot_time=as.numeric(format(b, "%H")) + as.numeric(format(b, "%M")) / 60)
subset_df <- df2[df2$non_zero==max(df2$non_zero),c("a","b","c","plot_time")]
時間を 1 つの連続変数にまとめる必要があるため、時間を選択しました。データを時間形式のままにしておくと、後で何かいじる必要があり、文字列形式 (「hh:mm」など) を使用すると、使用できる関数の種類が制限されます。連続数は最も柔軟なので、ここでは時間数を取得し、as.numeric(format(b, "%H"))
それを分数を 60 で割った値に加算してas.numeric(format(b, "%M")) / 60
、分を時間単位に変換します。また、より多くの列を扱っているため、最後のサブセット ステートメントを切り替えて、番号を参照するのではなく、必要な列に名前を付けました。連続した順序ではない列を処理すると、名前を使用する方がデバッグが容易であることがわかります。