2017-09-02 4 views
2

を与え、すべての二つの連続した日付の値の差を見つけるために、どのように自分のデータセットがどのように見えるかの簡易版である:Rプログラミング:ここでは、特定のID

total_sleepは時間で表現され
> df 
    ID total_sleep sleep_end_date 
1 1   9  2017-09-03 
2 1   8  2017-09-04 
3 1   7  2017-09-05 
4 1   10  2017-09-06 
5 1   11  2017-09-07 
6 2   5  2017-09-03 
7 2   12  2017-09-04 
8 2   4  2017-09-05 
9 2   3  2017-09-06 
10 2   6  2017-09-07 

私が見つけようとしているのは、特定のユーザーIDが与えられた場合、2つの連続する日付ごとの睡眠時間の絶対差です。希望の出力は次のようになります。

> df_answer 

    ID total_sleep sleep_end_date  diff_hours_of_sleep 
1 1   9  2017-09-03      NA 
2 1   8  2017-09-04      1 
3 1   7  2017-09-05      1 
4 1   10  2017-09-06      3 
5 1   11  2017-09-07      1 
6 2   5  2017-09-03      NA 
7 2   12  2017-09-04      7 
8 2   4  2017-09-05      8 
9 2   3  2017-09-06      1 
10 2   6  2017-09-08      NA 

NAは、前日に関するデータがないため、行1と6に表示されます。

私が前日(2017-09-07)に関するデータを持っていないので、最も重要なことに、NAは行10に表示されます。そして、これは私のためにコード化するのが最も難しい部分でした。

私はグーグル(意味: "stackoverflowed")これをdplyrの "データ暴言チートシート"を使用して解決策を見つけようとしましたが、私は何をすることができるようにする機能を見つけることができませんでした私はこれらの2つの変数を考慮に入れたい:日付と異なるユーザーID。

私はRの初心者ですから、何か簡単なことがありません。どんな入力や提案も大歓迎です!

+0

質問を編集しました! –

答えて

2
## Order data.frame by IDs, then by increasing sleep_end_dates (if not already sorted) 
df <- df[order(df$ID, df$sleep_end_date),] 

## Calculate difference in total_sleep with previous entry 
df$diff_hours_of_sleep <- c(NA,abs(diff(df$total_sleep))) 

## If previous ID is not equal, replace with diff_hours_of_sleep with NA 
ind <- c(NA, diff(df$ID)) 
df$diff_hours_of_sleep[ind != 0] <- NA 

## And if previous day wasn't yesterday, replace diff_hours_of_sleep with NA 
day_ind <- c(NA, diff(df$sleep_end_date)) 
df$diff_hours_of_sleep[day_ind != 1] <- NA 
+0

ありがとうございます!あなたの答えで私は私の質問で別の重要な点を見逃していたことに気付きました:前日のデータがないことがあります。私の質問で紹介した例のように、 –

+0

これを行う2つの新しい行が追加されました。 – dvantwisk

+0

それは動作します!ありがとうございました! –

1

多分次のようになります。ここで

df <- lapply(split(df, df$ID), function(x){ 
     y <- ifelse(diff(x$sleep_end_date) == 1, abs(diff(x$total_sleep)), NA) 
     x$diff_hours_of_sleep <- c(NA, y) 
     x 
}) 
df <- do.call(rbind, df) 
df 
0

はdata.tableを使用したソリューションである -

dt1 <- data.table(df, key=c('id', 'sleep_end_date')) 
merge(
    dt1[,.(id, total_sleep, sleep_end_date, i=.I - 1)], 
    dt1[,.(id, total_sleep, i=.I)], by=c('id','i'), all.x=TRUE) [,.(id,sleep_end_date,\ 
total_sleep.x,delta=total_sleep.y-total_sleep.x)] 
    id sleep_end_date total_sleep.x delta 
1: 1  2017-09-03    9 NA 
2: 1  2017-09-04    8  1 
3: 1  2017-09-05    7  1 
4: 1  2017-09-06   10 -3 
5: 1  2017-09-07   11 -1 
6: 2  2017-09-03    5 NA 
7: 2  2017-09-04   12 -7 
8: 2  2017-09-05    4  8 
9: 2  2017-09-06    3  1 
10: 2  2017-09-07    6 -3 

私はパフォーマンス比較は、純粋なdata.frameのアプローチと比較する方法わからないんだけど、うまくスケールするように見えるん。入力セットを20,000行に拡張すると、これは私のシステムでは1秒以下でした。

関連する問題