在 R 中为小于特定时间的时间间隔添加 NA 值
Adding NA values for time gaps less than a certain time in R
我有一个数据框(df;见下文),其中包含时间序列上的位置(多年,每小时给出位置)。数据中有很多差距,虽然我计划 运行 一个模型来估计一些缺失的位置,但我需要删除大于 10 小时的差距,因为我无法估计这段时间(即保持 10 小时或更短的间隔)。
数据集没有这些日期时间间隔的 NA 值。因此,我必须首先为指定日期范围内缺失的每个日期时间创建 NA 行(数据是从每年的 9 月 1 日到 12 月 01 日),然后删除 NA 差距大于 10 小时的行。
我将不得不 运行 使用不同的时间阈值和多个数据集进行此分析。因此,与其将此过程分为两步,不如只为特定的时间间隔大小添加 NA 值(为 10 小时或更短的时间间隔添加 NA)?这样就无需消除大于 10 小时的时间间隔。
以下是一些示例数据:
table <- "id date time lat lon
1 A 2011-10-03 05:00:00 35.02957 -53.36053
2 A 2011-10-03 06:00:00 35.11430 -53.39990
3 A 2011-10-03 09:00:00 35.14563 -53.40357
4 A 2011-10-03 10:00:00 36.22431 -53.57891
5 A 2011-10-03 23:00:00 36.60950 -53.56792
6 B 2012-11-08 05:00:00 35.84570 -53.36992
7 B 2012-11-08 07:00:00 35.99980 -53.36084
8 B 2012-11-08 10:00:00 36.45001 -53.37093
9 B 2012-11-08 23:00:00 36.56789 -53.38654
10 B 2012-11-09 05:00:00 36.62456 -53.50901"
#Create a dataframe with above table
df <- read.table(text=table, header = TRUE)
df
这是预期的输出:
table2 <- "id date time lat lon
1 A 2011-10-03 05:00:00 35.02957 -53.36053
2 A 2011-10-03 06:00:00 35.11430 -53.39990
3 A 2011-10-03 07:00:00 NA NA
4 A 2011-10-03 08:00:00 NA NA
5 A 2011-10-03 09:00:00 35.14563 -53.40357
6 A 2011-10-03 10:00:00 36.22431 -53.57891
7 A 2011-10-03 23:00:00 36.60950 -53.56792
8 B 2012-11-08 05:00:00 35.84570 -53.36992
9 B 2011-11-08 06:00:00 NA NA
10 B 2012-11-08 07:00:00 35.99980 -53.36084
11 B 2011-11-08 08:00:00 NA NA
12 B 2011-11-08 09:00:00 NA NA
13 B 2012-11-08 10:00:00 36.45001 -53.37093
14 B 2012-11-08 23:00:00 36.56789 -53.38654
15 B 2011-11-09 00:00:00 NA NA
16 B 2011-11-09 01:00:00 NA NA
17 B 2011-11-09 02:00:00 NA NA
18 B 2011-11-09 03:00:00 NA NA
19 B 2011-11-09 04:00:00 NA NA
20 B 2012-11-09 05:00:00 36.62456 -53.50901"
#Create a dataframe with the above table
expected <- read.table(text=table2, header = TRUE)
expected
编辑:
我应该补充一点,这段代码还需要考虑到有不同的ID,并且应该为每个ID单独考虑时间间隔,而不是跨所有ID(例如,不应在第5行和第6行之间添加时间间隔,因为这是两个不同 ID 之间的时间间隔)。
编辑 2:
Ronak Shah 的回答有效。但是,有时我也必须 运行 这段代码使用几分钟。例如,时间间隔为每 30 分钟一次,我想保持 1 hour/60 分钟的间隔(两个 30 分钟的间隔),但间隔不能超过此间隔。是否可以为此修改 Ronak Shah 的答案?
我试过将单位更改为“分钟”,>10 更改为“>60”,并在第二行中保留“小时”,但这只会让我在间隙中的每个小时都有一条 NA 行,当我真的想要每 30 分钟的间隙有一个 NA 时,除非那个小时有超过两个 30 分钟的间隙。我也尝试过其他迭代,这给我留下了很多 NA,而我真的每 30 分钟只想要一个,而且只有一个小时或更短的间隔。
df %>%
unite(datetime, date, time, sep = ' ') %>%
mutate(datetime = lubridate::ymd_hms(datetime)) %>%
group_by(id) %>%
group_by(grp = cumsum(difftime(datetime, lag(datetime, default = first(datetime)), units = 'mins') > 60), .add = TRUE) %>%
complete(datetime = seq(min(datetime), max(datetime), by = 'hour')) %>%
ungroup %>%
select(-grp)
这是使用 dplyr
和 tidyr
的方法。
合并 date
和 time
列为每个创建日期时间 id
创建一个 grp
列,为 10 小时以内的时间值创建一个新组。使用 complete
在每个组中创建最小和最大时间之间的缺失小时序列。
library(dplyr)
library(tidyr)
df %>%
unite(datetime, date, time, sep = ' ') %>%
mutate(datetime = lubridate::ymd_hms(datetime)) %>%
group_by(id) %>%
group_by(grp = cumsum(difftime(datetime, lag(datetime, default = first(datetime)), units = 'hours') > 10), .add = TRUE) %>%
complete(datetime = seq(min(datetime), max(datetime), by = 'hour')) %>%
ungroup %>%
select(-grp)
# id datetime lat lon
# <chr> <dttm> <dbl> <dbl>
# 1 A 2011-10-03 05:00:00 35.0 -53.4
# 2 A 2011-10-03 06:00:00 35.1 -53.4
# 3 A 2011-10-03 07:00:00 NA NA
# 4 A 2011-10-03 08:00:00 NA NA
# 5 A 2011-10-03 09:00:00 35.1 -53.4
# 6 A 2011-10-03 10:00:00 36.2 -53.6
# 7 A 2011-10-03 23:00:00 36.6 -53.6
# 8 B 2012-11-08 05:00:00 35.8 -53.4
# 9 B 2012-11-08 06:00:00 NA NA
#10 B 2012-11-08 07:00:00 36.0 -53.4
#11 B 2012-11-08 08:00:00 NA NA
#12 B 2012-11-08 09:00:00 NA NA
#13 B 2012-11-08 10:00:00 36.5 -53.4
#14 B 2012-11-08 23:00:00 36.6 -53.4
#15 B 2012-11-09 00:00:00 NA NA
#16 B 2012-11-09 01:00:00 NA NA
#17 B 2012-11-09 02:00:00 NA NA
#18 B 2012-11-09 03:00:00 NA NA
#19 B 2012-11-09 04:00:00 NA NA
#20 B 2012-11-09 05:00:00 36.6 -53.5
我有一个数据框(df;见下文),其中包含时间序列上的位置(多年,每小时给出位置)。数据中有很多差距,虽然我计划 运行 一个模型来估计一些缺失的位置,但我需要删除大于 10 小时的差距,因为我无法估计这段时间(即保持 10 小时或更短的间隔)。
数据集没有这些日期时间间隔的 NA 值。因此,我必须首先为指定日期范围内缺失的每个日期时间创建 NA 行(数据是从每年的 9 月 1 日到 12 月 01 日),然后删除 NA 差距大于 10 小时的行。
我将不得不 运行 使用不同的时间阈值和多个数据集进行此分析。因此,与其将此过程分为两步,不如只为特定的时间间隔大小添加 NA 值(为 10 小时或更短的时间间隔添加 NA)?这样就无需消除大于 10 小时的时间间隔。
以下是一些示例数据:
table <- "id date time lat lon
1 A 2011-10-03 05:00:00 35.02957 -53.36053
2 A 2011-10-03 06:00:00 35.11430 -53.39990
3 A 2011-10-03 09:00:00 35.14563 -53.40357
4 A 2011-10-03 10:00:00 36.22431 -53.57891
5 A 2011-10-03 23:00:00 36.60950 -53.56792
6 B 2012-11-08 05:00:00 35.84570 -53.36992
7 B 2012-11-08 07:00:00 35.99980 -53.36084
8 B 2012-11-08 10:00:00 36.45001 -53.37093
9 B 2012-11-08 23:00:00 36.56789 -53.38654
10 B 2012-11-09 05:00:00 36.62456 -53.50901"
#Create a dataframe with above table
df <- read.table(text=table, header = TRUE)
df
这是预期的输出:
table2 <- "id date time lat lon
1 A 2011-10-03 05:00:00 35.02957 -53.36053
2 A 2011-10-03 06:00:00 35.11430 -53.39990
3 A 2011-10-03 07:00:00 NA NA
4 A 2011-10-03 08:00:00 NA NA
5 A 2011-10-03 09:00:00 35.14563 -53.40357
6 A 2011-10-03 10:00:00 36.22431 -53.57891
7 A 2011-10-03 23:00:00 36.60950 -53.56792
8 B 2012-11-08 05:00:00 35.84570 -53.36992
9 B 2011-11-08 06:00:00 NA NA
10 B 2012-11-08 07:00:00 35.99980 -53.36084
11 B 2011-11-08 08:00:00 NA NA
12 B 2011-11-08 09:00:00 NA NA
13 B 2012-11-08 10:00:00 36.45001 -53.37093
14 B 2012-11-08 23:00:00 36.56789 -53.38654
15 B 2011-11-09 00:00:00 NA NA
16 B 2011-11-09 01:00:00 NA NA
17 B 2011-11-09 02:00:00 NA NA
18 B 2011-11-09 03:00:00 NA NA
19 B 2011-11-09 04:00:00 NA NA
20 B 2012-11-09 05:00:00 36.62456 -53.50901"
#Create a dataframe with the above table
expected <- read.table(text=table2, header = TRUE)
expected
编辑:
我应该补充一点,这段代码还需要考虑到有不同的ID,并且应该为每个ID单独考虑时间间隔,而不是跨所有ID(例如,不应在第5行和第6行之间添加时间间隔,因为这是两个不同 ID 之间的时间间隔)。
编辑 2:
Ronak Shah 的回答有效。但是,有时我也必须 运行 这段代码使用几分钟。例如,时间间隔为每 30 分钟一次,我想保持 1 hour/60 分钟的间隔(两个 30 分钟的间隔),但间隔不能超过此间隔。是否可以为此修改 Ronak Shah 的答案?
我试过将单位更改为“分钟”,>10 更改为“>60”,并在第二行中保留“小时”,但这只会让我在间隙中的每个小时都有一条 NA 行,当我真的想要每 30 分钟的间隙有一个 NA 时,除非那个小时有超过两个 30 分钟的间隙。我也尝试过其他迭代,这给我留下了很多 NA,而我真的每 30 分钟只想要一个,而且只有一个小时或更短的间隔。
df %>%
unite(datetime, date, time, sep = ' ') %>%
mutate(datetime = lubridate::ymd_hms(datetime)) %>%
group_by(id) %>%
group_by(grp = cumsum(difftime(datetime, lag(datetime, default = first(datetime)), units = 'mins') > 60), .add = TRUE) %>%
complete(datetime = seq(min(datetime), max(datetime), by = 'hour')) %>%
ungroup %>%
select(-grp)
这是使用 dplyr
和 tidyr
的方法。
合并 date
和 time
列为每个创建日期时间 id
创建一个 grp
列,为 10 小时以内的时间值创建一个新组。使用 complete
在每个组中创建最小和最大时间之间的缺失小时序列。
library(dplyr)
library(tidyr)
df %>%
unite(datetime, date, time, sep = ' ') %>%
mutate(datetime = lubridate::ymd_hms(datetime)) %>%
group_by(id) %>%
group_by(grp = cumsum(difftime(datetime, lag(datetime, default = first(datetime)), units = 'hours') > 10), .add = TRUE) %>%
complete(datetime = seq(min(datetime), max(datetime), by = 'hour')) %>%
ungroup %>%
select(-grp)
# id datetime lat lon
# <chr> <dttm> <dbl> <dbl>
# 1 A 2011-10-03 05:00:00 35.0 -53.4
# 2 A 2011-10-03 06:00:00 35.1 -53.4
# 3 A 2011-10-03 07:00:00 NA NA
# 4 A 2011-10-03 08:00:00 NA NA
# 5 A 2011-10-03 09:00:00 35.1 -53.4
# 6 A 2011-10-03 10:00:00 36.2 -53.6
# 7 A 2011-10-03 23:00:00 36.6 -53.6
# 8 B 2012-11-08 05:00:00 35.8 -53.4
# 9 B 2012-11-08 06:00:00 NA NA
#10 B 2012-11-08 07:00:00 36.0 -53.4
#11 B 2012-11-08 08:00:00 NA NA
#12 B 2012-11-08 09:00:00 NA NA
#13 B 2012-11-08 10:00:00 36.5 -53.4
#14 B 2012-11-08 23:00:00 36.6 -53.4
#15 B 2012-11-09 00:00:00 NA NA
#16 B 2012-11-09 01:00:00 NA NA
#17 B 2012-11-09 02:00:00 NA NA
#18 B 2012-11-09 03:00:00 NA NA
#19 B 2012-11-09 04:00:00 NA NA
#20 B 2012-11-09 05:00:00 36.6 -53.5