【问题标题】:R programming: How to find a difference in value for every two consecutive dates, given a specific ID [duplicate]R编程:如何在给定特定ID的情况下找到每两个连续日期的值差异[重复]
【发布时间】:2017-09-02 15:51:59
【问题描述】:

这是我的数据集的简化版本:

 > 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

total_sleep 以小时为单位。

在给定特定用户 ID 的情况下,我想要找到的是每两个连续日期的睡眠时间的绝对差异。所需的输出应如下所示:

> 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 行中,因为它没有关于前一天的任何数据。

最重要的是,NA 出现在第 10 行,因为我没有关于前一天 (2017-09-07) 的任何数据。这对我来说是最棘手的部分。

我已经用谷歌搜索了(意思是:“stackoverflowed”),并尝试使用 dplyr 的“数据整理备忘单”找到解决方案,但我一直无法找到一个功能让我能够做我想做的事需要考虑这两个变量:日期和不同的用户 ID。

我是 R 的初学者,所以我确实可能遗漏了一些简单的东西。非常欢迎任何意见或建议!

【问题讨论】:

  • 已编辑问题!

标签: r


【解决方案1】:
## 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 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

【讨论】:

  • 谢谢!我在你的回答中意识到我在我的问题中遗漏了另一个重要的观点:有时我没有前一天的数据,我想在这些情况下生成一个 NA,就像我在我的问题中介绍的示例一样。
  • 刚刚添加了两个新的行。
  • 有效!谢谢!
【解决方案2】:

也许下面的就可以了。

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

【讨论】:

    【解决方案3】:

    这是一个使用 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 行,这在我的系统上花费了不到一秒钟的时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-03
      • 1970-01-01
      • 2021-04-01
      • 2020-09-23
      • 2017-06-22
      • 1970-01-01
      • 2017-07-07
      • 2012-10-05
      相关资源
      最近更新 更多