如何删除第一个完整分钟之前的秒数
How to remove seconds before the first full minute
我目前有来自加速度计的逐秒数据,我需要按分钟计算平均值(平均 60 秒)。问题是我在第一分钟和最后一分钟的开始和结束时的数据不是整分钟。我想删除那些秒数,所以当我按分钟平均时,它总是在分钟开始和停止。我的数据也是多个参与者堆叠在一起,所以我需要通过 id 来完成。下面是我的数据布局示例:
ID Timestamp
*1 2017-03-15 10:29:58
1 2017-03-15 10:29:59*
1 2017-03-15 10:30:00
1 2017-03-15 10:30:01
...
*1 2017-03-15 12:48:00*
*1 2017-03-15 12:48:01*
*1 2017-03-15 12:48:02*
*2 2017-04-01 11:19:59*
2 2017-03-15 11:20:00
等等
希望我能做到这一点,我可以消除每个 ID 的斜体行,这样我每个人只有完整的分钟数。 (我每个数据帧大约有 80-95 个 ID)。这将允许我按整分钟汇总。
如果有一种更简单的方法来对整分钟的值进行平均而不需要我删除行,那可能会更容易。
由于您用 lubridate
标记了它,这里有一个 lubridate
/tidyverse
解决方案。 (如果我没有正确理解你的问题。)
library(tidyverse)
library(lubridate)
df <- tibble::tribble(
~id, ~timestamp,
1, "2017-03-15 10:29:58",
1, "2017-03-15 10:29:59",
1, "2017-03-15 10:30:00",
1, "2017-03-15 10:30:01",
1, "2017-03-15 12:48:00",
1, "2017-03-15 12:48:01",
1, "2017-03-15 12:48:02",
2, "2017-04-01 11:19:59",
2, "2017-03-15 11:20:00"
) %>%
mutate(
timestamp = as_datetime(timestamp),
x = rnorm(n()) # some var you want aggregate
)
如果您只想保留您所说的 "whole minute" 的观察结果,则保留观察结果的时间戳与按分钟计算时相同。
df %>%
filter(timestamp == floor_date(timestamp, "minute"))
如果您没有与下限时间戳完全匹配的观测值,但您希望保留最接近 "whole minute" 的观测值,那么您可以按时间戳排列它们并将第一个保留在每分钟。
df %>%
arrange(timestamp) %>%
mutate(min = floor_date(timestamp, "minute")) %>%
group_by(min, id) %>%
slice(1) %>%
ungroup()
如果你想按分钟聚合一些变量 x,比如说,取平均值,然后按下限时间戳分组。
df %>%
mutate(min = floor_date(timestamp, "minute")) %>%
group_by(min, id) %>%
summarize(mean_var = mean(var)) %>%
ungroup()
这是另一个 lubridate
和 tidyverse
方法,使用 Gregor 的评论建议。由于我们期望整分钟观察有 60 个观察,因此我们可以过滤掉没有 60 个的观察。我创建了一个略长于一分钟的跨度来说明。如果你的时间跨度超过一个小时(所以分钟重复),也只需使用 hour()
制作一个小时列并对其进行分组。
library(tidyverse)
library(lubridate)
tbl <- tibble(
time = ymd_hms("2017-03-15 10:29:57") + 1:66
)
head(tbl)
#> # A tibble: 6 x 1
#> time
#> <dttm>
#> 1 2017-03-15 10:29:58
#> 2 2017-03-15 10:29:59
#> 3 2017-03-15 10:30:00
#> 4 2017-03-15 10:30:01
#> 5 2017-03-15 10:30:02
#> 6 2017-03-15 10:30:03
tail(tbl)
#> # A tibble: 6 x 1
#> time
#> <dttm>
#> 1 2017-03-15 10:30:58
#> 2 2017-03-15 10:30:59
#> 3 2017-03-15 10:31:00
#> 4 2017-03-15 10:31:01
#> 5 2017-03-15 10:31:02
#> 6 2017-03-15 10:31:03
tbl %>%
mutate(minute = minute(time)) %>%
group_by(minute) %>%
filter(n() == 60)
#> # A tibble: 60 x 2
#> # Groups: minute [1]
#> time minute
#> <dttm> <int>
#> 1 2017-03-15 10:30:00 30
#> 2 2017-03-15 10:30:01 30
#> 3 2017-03-15 10:30:02 30
#> 4 2017-03-15 10:30:03 30
#> 5 2017-03-15 10:30:04 30
#> 6 2017-03-15 10:30:05 30
#> 7 2017-03-15 10:30:06 30
#> 8 2017-03-15 10:30:07 30
#> 9 2017-03-15 10:30:08 30
#> 10 2017-03-15 10:30:09 30
#> # ... with 50 more rows
由 reprex package (v0.2.0) 创建于 2018-05-09。
我目前有来自加速度计的逐秒数据,我需要按分钟计算平均值(平均 60 秒)。问题是我在第一分钟和最后一分钟的开始和结束时的数据不是整分钟。我想删除那些秒数,所以当我按分钟平均时,它总是在分钟开始和停止。我的数据也是多个参与者堆叠在一起,所以我需要通过 id 来完成。下面是我的数据布局示例:
ID Timestamp
*1 2017-03-15 10:29:58
1 2017-03-15 10:29:59*
1 2017-03-15 10:30:00
1 2017-03-15 10:30:01
...
*1 2017-03-15 12:48:00*
*1 2017-03-15 12:48:01*
*1 2017-03-15 12:48:02*
*2 2017-04-01 11:19:59*
2 2017-03-15 11:20:00
等等
希望我能做到这一点,我可以消除每个 ID 的斜体行,这样我每个人只有完整的分钟数。 (我每个数据帧大约有 80-95 个 ID)。这将允许我按整分钟汇总。
如果有一种更简单的方法来对整分钟的值进行平均而不需要我删除行,那可能会更容易。
由于您用 lubridate
标记了它,这里有一个 lubridate
/tidyverse
解决方案。 (如果我没有正确理解你的问题。)
library(tidyverse)
library(lubridate)
df <- tibble::tribble(
~id, ~timestamp,
1, "2017-03-15 10:29:58",
1, "2017-03-15 10:29:59",
1, "2017-03-15 10:30:00",
1, "2017-03-15 10:30:01",
1, "2017-03-15 12:48:00",
1, "2017-03-15 12:48:01",
1, "2017-03-15 12:48:02",
2, "2017-04-01 11:19:59",
2, "2017-03-15 11:20:00"
) %>%
mutate(
timestamp = as_datetime(timestamp),
x = rnorm(n()) # some var you want aggregate
)
如果您只想保留您所说的 "whole minute" 的观察结果,则保留观察结果的时间戳与按分钟计算时相同。
df %>%
filter(timestamp == floor_date(timestamp, "minute"))
如果您没有与下限时间戳完全匹配的观测值,但您希望保留最接近 "whole minute" 的观测值,那么您可以按时间戳排列它们并将第一个保留在每分钟。
df %>%
arrange(timestamp) %>%
mutate(min = floor_date(timestamp, "minute")) %>%
group_by(min, id) %>%
slice(1) %>%
ungroup()
如果你想按分钟聚合一些变量 x,比如说,取平均值,然后按下限时间戳分组。
df %>%
mutate(min = floor_date(timestamp, "minute")) %>%
group_by(min, id) %>%
summarize(mean_var = mean(var)) %>%
ungroup()
这是另一个 lubridate
和 tidyverse
方法,使用 Gregor 的评论建议。由于我们期望整分钟观察有 60 个观察,因此我们可以过滤掉没有 60 个的观察。我创建了一个略长于一分钟的跨度来说明。如果你的时间跨度超过一个小时(所以分钟重复),也只需使用 hour()
制作一个小时列并对其进行分组。
library(tidyverse)
library(lubridate)
tbl <- tibble(
time = ymd_hms("2017-03-15 10:29:57") + 1:66
)
head(tbl)
#> # A tibble: 6 x 1
#> time
#> <dttm>
#> 1 2017-03-15 10:29:58
#> 2 2017-03-15 10:29:59
#> 3 2017-03-15 10:30:00
#> 4 2017-03-15 10:30:01
#> 5 2017-03-15 10:30:02
#> 6 2017-03-15 10:30:03
tail(tbl)
#> # A tibble: 6 x 1
#> time
#> <dttm>
#> 1 2017-03-15 10:30:58
#> 2 2017-03-15 10:30:59
#> 3 2017-03-15 10:31:00
#> 4 2017-03-15 10:31:01
#> 5 2017-03-15 10:31:02
#> 6 2017-03-15 10:31:03
tbl %>%
mutate(minute = minute(time)) %>%
group_by(minute) %>%
filter(n() == 60)
#> # A tibble: 60 x 2
#> # Groups: minute [1]
#> time minute
#> <dttm> <int>
#> 1 2017-03-15 10:30:00 30
#> 2 2017-03-15 10:30:01 30
#> 3 2017-03-15 10:30:02 30
#> 4 2017-03-15 10:30:03 30
#> 5 2017-03-15 10:30:04 30
#> 6 2017-03-15 10:30:05 30
#> 7 2017-03-15 10:30:06 30
#> 8 2017-03-15 10:30:07 30
#> 9 2017-03-15 10:30:08 30
#> 10 2017-03-15 10:30:09 30
#> # ... with 50 more rows
由 reprex package (v0.2.0) 创建于 2018-05-09。