首页 文章

如何通过两个变量进行分组和汇总

提问于
浏览
0

我在多列上使用group_by()时遇到问题 . 示例数据集如下:

dput(test)
structure(list(timestamp = structure(c(1506676980, 1506676980, 
1506676980, 1506677040, 1506677280, 1506677340, 1506677460), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), plusminus = c(-1, 1, 1, 1, 1, 1, -1
), AP = structure(c(1L, 2L, 2L, 2L, 2L, 1L, 2L), .Label = c("A", 
"B"), class = "factor")), .Names = c("timestamp", "plusminus", 
"AP"), row.names = c(NA, -7L), class = "data.frame")

它看起来如下:

timestamp plusminus AP
1 2017-09-29 09:23:00        -1  A
2 2017-09-29 09:23:00         1  B
3 2017-09-29 09:23:00         1  B
4 2017-09-29 09:24:00         1  B
5 2017-09-29 09:28:00         1  B
6 2017-09-29 09:29:00         1  A
7 2017-09-29 09:31:00        -1  B

我想做以下事情:

  • 计算'AP'变量中每个级别的运行总计

  • 为每分钟聚合运行总计的最大值 .

换句话说,我想要这个输出:

timestamp total AP
1 2017-09-29 09:23:00    -1  A
2 2017-09-29 09:23:00     2  B
3 2017-09-29 09:24:00     3  B
4 2017-09-29 09:28:00     4  B
5 2017-09-29 09:29:00     0  A
6 2017-09-29 09:31:00     3  B

通过以下方式轻松完成第1部分:

test %>% group_by(AP) %>% mutate(total = cumsum(plusminus))

这使:

# A tibble: 7 x 4
# Groups:   AP [2]
            timestamp plusminus     AP total
               <dttm>     <dbl> <fctr> <dbl>
1 2017-09-29 09:23:00        -1      A    -1
2 2017-09-29 09:23:00         1      B     1
3 2017-09-29 09:23:00         1      B     2
4 2017-09-29 09:24:00         1      B     3
5 2017-09-29 09:28:00         1      B     4
6 2017-09-29 09:29:00         1      A     0
7 2017-09-29 09:31:00        -1      B     3

但是我不知道如何做第2部分 . 也就是说,我想知道如何执行聚合,以便后一个数据帧中的第二行被压缩以提供所需的输出 .

2 回答

  • 0

    计算运行总计后,需要重新分组以将每个时间戳-AP对组合在一起,然后汇总以保持最大值 . 如果你想保留最后一个值(而不是最大值),你可以保留最后一行(你也可以使用 slice(n()) ) . 在这里,答案是相同的,但请确保您的数据是这样的 .

    test %>%
      group_by(AP) %>%
      mutate(total = cumsum(plusminus)) %>%
      group_by(timestamp, AP) %>%
      summarise(maxTotal = max(total)
                , lastTotal = total[n()])
    

    timestamp     AP maxTotal lastTotal
                   <dttm> <fctr>    <dbl>     <dbl>
    1 2017-09-29 09:23:00      A       -1        -1
    2 2017-09-29 09:23:00      B        2         2
    3 2017-09-29 09:24:00      B        3         3
    4 2017-09-29 09:28:00      B        4         4
    5 2017-09-29 09:29:00      A        0         0
    6 2017-09-29 09:31:00      B        3         3
    
  • 1

    这是一个 data.table 方法:

    DATA

    p <- structure(list(timestamp = structure(c(1506676980, 1506676980, 
    1506676980, 1506677040, 1506677280, 1506677340, 1506677460), class = c("POSIXct", 
    "POSIXt"), tzone = "UTC"), plusminus = c(-1, 1, 1, 1, 1, 1, -1
    ), AP = structure(c(1L, 2L, 2L, 2L, 2L, 1L, 2L), .Label = c("A", 
    "B"), class = "factor")), .Names = c("timestamp", "plusminus", 
    "AP"), row.names = c(NA, -7L), class = "data.frame")
    

    CODE

    library(data.table)
    p <- as.data.table(p)
    p[, total:= cumsum(plusminus), by = AP][, max(total), by = .(AP, lubridate::round_date(timestamp, unit = "min"))]
    

    OUTPUT

    AP           lubridate V1
    1:  A 2017-09-29 09:23:00 -1
    2:  B 2017-09-29 09:23:00  2
    3:  B 2017-09-29 09:24:00  3
    4:  B 2017-09-29 09:28:00  4
    5:  A 2017-09-29 09:29:00  0
    6:  B 2017-09-29 09:31:00  3
    

    以上代码段使用"chaining"(您可以将其视为类似于 %>% 方法)以获得所需的输出 . 首先,我们通过 AP 获得累计和,并将其保存到 total . 在第二步中,我们按 APtimestamp (到最近的分钟)进行分组,并获得新定义的变量 total 的最大值 .

    我发现 data.table 有一个非常干净的方法,适用于大型数据集 .

相关问题