汇总数据并保留日期列值

时间:2017-07-26 08:57:17

标签: r date sum

之前我问了一个类似的问题,得到了一个很好的答案,但需要一些关于总结和日期的更多指导。 Summarize and count data in R with dplyr

目标:

在我的新数据集中,我有一个包含日期的列,当事件发生时。当我想按照另一篇文章中的建议继续进行示例时,我收到一条错误消息:

数据集:

structure(list(User = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L,  2L, 2L, 2L),
Date = c("25.11.2015 13:59", "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", "05.01.2016 13:22", 
"06.01.2016 09:18", "14.02.2016 22:47",  
"20.02.2016 21:27", "01.04.2016 13:52", "24.07.2016 07:03"), 
    StimuliA = c(0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 1L), StimuliB = c(0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 
    1L, 0L, 0L, 0L), R2 = c(1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 1L, 1L, 0L), R3 = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 1L, 
    0L, 0L, 0L, 0L), R4 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), R5 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L), R6 = c(0L, 0L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 
    0L, 0L, 0L, 0L), R7 = c(0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 
    0L, 0L, 0L, 0L), stims = c("0_0", "0_0", "1_0", "1_0", "1_1", 
    "1_1", "1_1", "1_1", "1_1", "1_2", "1_2", "1_2", "2_2")), .Names = c("User",  "Date", "StimuliA", "StimuliB", "R2", "R3", "R4", "R5", "R6",  "R7", "stims"), row.names = c(NA, -13L), 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")), R2 = structure(list(), class = c("collector_integer", 
    "collector")), R3 = structure(list(), class = c("collector_integer", 
    "collector")), R4 = structure(list(), class = c("collector_integer", 
    "collector")), R5 = structure(list(), class = c("collector_integer", 
    "collector")), R6 = structure(list(), class = c("collector_integer", 
    "collector")), R7 = structure(list(), class = c("collector_integer", 
    "collector"))), .Names = c("User", "Date", "StimuliA", "StimuliB", 
    "R2", "R3", "R4", "R5", "R6", "R7")), default = structure(list(), class = c("collector_guess", 
    "collector"))), .Names = c("cols", "default"), class = "col_spec"), class = c("tbl_df",  "tbl", "data.frame"))

代码:

df$stims <- with(df, paste(cumsum(StimuliA), cumsum(StimuliB), sep="_"))    
aggregate(. ~ User + stims, data=df, sum)
Error in Summary.factor(c(12L, 2L), na.rm = FALSE) : 
‘sum’ not meaningful for factors

问题/期望的结果: 在我的结果中,我想保留刺激发生的日期(或刺激A和B为0,然后是特定用户的第一个日期)

User    Date         StimuliA   StimuliB    R2  R3  R4  R5  R6  R7
 1  25.11.2015 13:59     0         0        1   0   0   0   0   1
 1  07.12.2015 08:18     1         0        0   0   0   0   1   0
 1  08.12.2015 19:40     0         1        0   2   0   0   1   1
 2  05.01.2016 13:22     0         0        0   0   0   0   1   0 
 2  14.02.2016 22:47     0         1        2   0   0   0   0   0
 2  24.07.2016 07:03     1         0        0   0   0   0   0   0

在这个结果表中,当刺激A和B仍为0时,我们得到值的总和(R2-R7)。[Line1]然后对于每个刺激,存在R2-R7的总和,直到下一个刺激发生。

这是在上一篇文章中提出的,但我无法使其发挥作用:

  

您不希望将日期作为因素。将日期转换为   使用as.Date的日期变量(在SO上有很多帖子)。一种方法   然后是用户和单独聚合日期变量   与上述类似的,取最小值而不是总和。然后合并   两个结果data.frames。如果这没有意义,那可能会   值得问一个链接到这个问题的新问题,添加   日期变量的附加问题。还包括一个例子   包含此变量@lmo

的数据集

2 个答案:

答案 0 :(得分:2)

此处,Date设置为POSIXct类,以保留日期时间,这对此任务至关重要。 as.Date()将删除该日期的时间。

library(dplyr)

union_all(
    df %>%
      mutate(Date = as.POSIXct(strptime(Date, "%d.%m.%Y %H:%M"))) %>% 
      filter(StimuliA == 0, StimuliB == 0, Date == min(Date)),
    df %>%
      mutate(Date = as.POSIXct(strptime(Date, "%d.%m.%Y %H:%M"))) %>% 
      filter(StimuliA == 1 | StimuliB == 1)) %>% 
  arrange(User, Date) %>% 
  select(-stims)

输出:

     User                Date StimuliA StimuliB    R2    R3    R4    R5    R6    R7
    <int>              <dttm>    <int>    <int> <int> <int> <int> <int> <int> <int>
  1     1 2015-11-25 13:59:00        0        0     1     0     0     0     0     0
  2     1 2015-12-07 08:18:00        1        0     0     0     0     0     0     0
  3     1 2015-12-08 19:40:00        0        1     0     0     0     0     0     0
  4     2 2016-02-14 22:47:00        0        1     0     0     0     0     0     0
  5     2 2016-07-24 07:03:00        1        0     0     0     0     0     0     0

答案 1 :(得分:1)

通过dplyr的一个想法是过滤所有非刺激并抓住每个用户的第一个观察(通过slice)。过滤所有刺激和bind_rows,即

library(dplyr)

bind_rows(
  df %>% 
    filter(rowSums(.[3:4]) == 0) %>% 
    group_by(User) %>%
    slice(1L), 
  df %>% 
    filter(rowSums(.[3:4]) != 0)) %>% 
  arrange(User)

由此给出,

# A tibble: 6 x 11
# Groups:   User [2]
   User             Date StimuliA StimuliB    R2    R3    R4    R5    R6    R7 stims
  <int>            <chr>    <int>    <int> <int> <int> <int> <int> <int> <int> <chr>
1     1 25.11.2015 13:59        0        0     1     0     0     0     0     0   0_0
2     1 07.12.2015 08:18        1        0     0     0     0     0     0     0   1_0
3     1 08.12.2015 19:40        0        1     0     0     0     0     0     0   1_1
4     2 05.01.2016 13:22        0        0     0     0     0     0     1     0   1_1
5     2 14.02.2016 22:47        0        1     0     0     0     0     0     0   1_2
6     2 24.07.2016 07:03        1        0     0     0     0     0     0     0   2_2