我在多列上使用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
我想做以下事情:
换句话说,我想要这个输出:
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部分。也就是说,我想知道如何执行聚合,以便后一个数据帧中的第二行被压缩以提供所需的输出。
答案 0 :(得分:1)
计算运行总计后,需要重新分组以将每个时间戳-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 :(得分:1)
以下是data.table
方法:
数据强>
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"))]
<强>输出强>
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
以上代码段使用&#34; chaining&#34; (您可以认为它类似于%>%
方法)以获得所需的输出。首先,我们得到AP
的累计和,并将其保存到total
。在第二步中,我们按AP
和timestamp
分组(到最近的分钟)并获取新定义的变量total
的最大值。
我发现data.table
有一个非常干净的方法,适用于大型数据集。