【问题标题】:Calculate difference between two values in grouped sequences计算分组序列中两个值之间的差异
【发布时间】:2017-07-28 17:25:31
【问题描述】:

这是这篇文章的后续问题: Loop through dataframe in R and measure time difference between two values

我已经通过以下代码获得了很好的帮助,以计算某个刺激和下一个响应之间的时间差(以分钟为单位):

df$Date <- as.POSIXct(strptime(df$Date,"%d.%m.%Y %H:%M"))
df %>%
  arrange(User,Date)%>%
  mutate(difftime= difftime(lead(Date),Date, units = "mins") ) %>%
  group_by(User)%>%
  filter((StimuliA==1 | StimuliB==1) & lead(Responses)==1)`

数据集:

structure(list(User = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 
4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L), Date = c("24.11.2015 20:39", 
"25.11.2015 11:42", "11.01.2016 22:46", "26.11.2015 22:42", "04.03.2016 05:45", 
"24.11.2015 13:13", "25.11.2015 13:59", "27.11.2015 12:18", "28.05.2016 06:49", 
"06.07.2016 09:46", "03.12.2015 09:32", "07.12.2015 08:18", "08.12.2015 19:40", 
"08.12.2015 19:40", "22.12.2015 08:50", "22.12.2015 08:52", "22.12.2015 08:52", 
"22.12.2015 20:46"), StimuliA = c(1L, 0L, 0L, 1L, 1L, 1L, 0L, 
1L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L), StimuliB = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 
0L), Responses = c(0L, 1L, 1L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 0L, 
0L, 1L, 0L, 1L, 1L, 1L, 1L)), .Names = c("User", "Date", "StimuliA", 
"StimuliB", "Responses"), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -18L), spec = structure(list(cols = structure(list(
    User = structure(list(), class = c("collector_integer", "collector"
    )), Date = structure(list(), class = c("collector_character", 
    "collector")), StimuliA = structure(list(), class = c("collector_integer", 
    "collector")), StimuliB = structure(list(), class = c("collector_integer", 
    "collector")), Responses = structure(list(), class = c("collector_integer", 
    "collector"))), .Names = c("User", "Date", "StimuliA", "StimuliB", 
"Responses")), default = structure(list(), class = c("collector_guess", 
"collector"))), .Names = c("cols", "default"), class = "col_spec"))

目标/问题 lead 参数有助于确定刺激 == 1(A 或 B)与下一个响应 [按日期/时间排序](响应 == 1)。我将如何更改该代码以找到该序列中刺激 A 或 B 与 LAST 响应之间的时间差。 (直到下一个刺激发生)

期望的输出:

User    Date        StimuliA    StimuliB    Responses   time diff  Seq_ID
1   24.11.2015 20:39    1           0           0                  1_1_0
1   25.11.2015 11:42    0           0           1                  1_1_0
1   11.01.2016 22:46    0           0           1       69247      1_1_0
2   26.11.2015 22:42    1           0           0                  2_1_0
2   04.03.2016 05:45    0           1           0                  2_1_1
3   24.11.2015 13:13    1           0           0                  3_1_0
3   25.11.2015 13:59    0           0           1       1486       3_1_0
3   27.11.2015 12:18    1           0           0                  3_2_0
3   28.05.2016 06:49    0           0           1                  3_2_0
3   06.07.2016 09:46    0           0           1       319528     3_2_0
4   03.12.2015 09:32    1           0           0                  4_1_0
4   07.12.2015 08:18    1           0           0                  4_2_0
4   08.12.2015 19:40    0           0           1       2122       4_1_0
4   08.12.2015 19:40    0           1           0                  4_2_1
4   22.12.2015 08:50    0           0           1       19510      4_2_1
5   22.12.2015 08:52    0           0           1                  5_0_0
5   22.12.2015 08:52    0           0           1                  5_0_0
5   22.12.2015 20:46    0           0           1                  5_0_0

对于刺激 A,这意味着值 c(69247, 319528, 2122) 和 B c(1486, 19510)。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    试试这个。

    # df$Date <- as.POSIXct(strptime(df$Date,"%d.%m.%Y %H:%M"))
    df %>% 
      arrange(User, Date) %>% 
      group_by(User) %>%
      mutate(
        last.date = Date[which(StimuliA == 1L)[c(1,1:sum(StimuliA == 1L))][cumsum(StimuliA == 1L)+ 1]]
      ) %>%
      mutate(
        timesince = ifelse(Responses == 1L, Date - last.date, NA)
      )
    

    首先创建一个记录上次刺激数据的列,然后使用ifelselag 获取当前日期和上次刺激日期之间的差异。您可以filter 仅提取 LAST 响应。

    有一种更简洁的方法可以使用 zoo.na.locf 执行“last.date”操作,但我不想假设您对另一个包依赖项没问题。

    编辑要识别序列(如果我正确理解“序列”的含义),请继续使用

    %>% mutate(sequence = cumsum(StimuliA))
    

    识别定义为跟随积极刺激的观察的序列。要过滤掉序列的最后一个响应,请使用

    继续链
    %>% group_by(User, sequence) %>%
      filter(timesince == max(timesince, na.rm = TRUE))
    

    按序列(和用户)分组,然后提取与每个序列相关的最大时间差(这将对应于序列的最后一个肯定响应)。

    【讨论】:

    • 我尝试了您的解决方案,它有效。谢谢你!您将如何过滤序列中的最后一个日期?或者你会如何识别它?
    • 谢谢!很明显,我可以用 max 来实现这一点。再次感谢您的帮助
    • @svnnf,这最终没有奏效吗?我在自己的代码中使用了类似的东西,所以如果你发现了一个问题,我想知道它。
    • 对不起,我在回答时受到干扰。确实我有问题。目前我得到一些日期的负值,因为最后一个日期只关注 StimuliA 而不是 B。我现在创建了一个特定的 ID,它将 USERID 与 Stimuli 结合在一起。 (UserID_#StimuliA_#StimuliB) 刺激的计数仅针对每个用户。这可以识别每个唯一的序列,然后我们可以得到序列的最后日期?或者您将如何在必须考虑的 2 个刺激中工作?
    • 我在上面的示例中添加了ID
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    相关资源
    最近更新 更多