根据唯一的开始和结束日期 [R] 从时间序列中过滤列(将第 1 行标准化为每个列的第一天)
Filtering columns from a timeseries based on unique start and end dates [R] (to standardize row 1 as day one for each)
我正在尝试标准化 table timeseries
中列的开始日期,以便每个列都根据我在另一个 table StartEnd
中的预定义值开始. timeseries
中的 datetime
与此问题中的所有日期值一样采用 POSIXct 格式。
我如何创建一个数据框,其中每列的第一行都以 Start
处的值开头,同时还删除 End
处的 0 个值?这是在对堆叠数据集进行 spread() 之后:
timeseries <- spread(timeseries, ID, Count , fill = "0")
我研究过过滤器,但我不确定 dplyr 是否适合这里。我认为某种功能可以解决,但以我有限的知识,我不知道在这种情况下一个人的结构会是什么样子。 Jfyi 我是自学 R 的,除了一些 Coursera 课程外,没有接受过正规的编码教育。
timeseries
:
datetime ID1 ID2 ID3 ID4 ID5 ID6 ID7
1 01/01/19 00:00:00 0 0 7 1 1 0 0
2 01/01/19 01:00:00 0 0 11 2 2 0 0
3 01/01/19 02:00:00 0 0 6 3 3 0 0
4 01/01/19 03:00:00 3 0 10 0 4 0 0
5 01/01/19 04:00:00 4 0 3 0 5 0 0
6 01/01/19 06:00:00 5 1 1 0 6 0 1
7 01/01/19 07:00:00 6 2 1 0 7 0 3
8 01/01/19 09:00:00 0 3 2 0 0 1 0
9 01/01/19 10:00:00 1 4 3 0 0 2 1
StartEnd
:
SomeID Start End
ID1 01/01/19 03:00:00 01/01/19 10:00:00
ID2 01/01/19 06:00:00 01/01/19 10:00:00
ID3 01/01/19 00:00:00 01/01/19 10:00:00
ID4 01/01/19 00:00:00 01/01/19 02:00:00
ID5 01/01/19 00:00:00 01/01/19 07:00:00
ID6 01/01/19 09:00:00 01/01/19 10:00:00
ID7 01/01/19 06:00:00 01/01/19 10:00:00
预期输出:
ID1 ID2 ID3 ID4 ID5 ID6 ID7
1 3 1 7 1 1 1 1
2 4 2 11 2 2 2 3
3 5 3 6 3 3 0
4 6 4 10 4 1
5 0 3 5
6 1 1 6
7 1 7
8 2
9 3
我们可以得到 timeseries
的长格式,将其与 StartEnd
数据框连接,将日期时间列转换为 POSIXct
格式,filter
[=] 之间的值15=] 和 End
并以宽格式获取数据。
library(dplyr)
library(tidyr)
timeseries %>%
pivot_longer(cols = -datetime, names_to = 'SomeID') %>%
left_join(StartEnd, by = 'SomeID') %>%
mutate_at(vars(datetime, Start, End), lubridate::dmy_hms) %>%
filter(datetime >= Start & datetime <= End) %>%
select(SomeID, value) %>%
group_by(SomeID) %>%
mutate(row = row_number()) %>%
pivot_wider(names_from = SomeID, values_from = value) %>%
select(-row) %>%
select(paste0("ID", 1:7))
# A tibble: 9 x 7
# ID1 ID2 ID3 ID4 ID5 ID6 ID7
# <int> <int> <int> <int> <int> <int> <int>
#1 3 1 7 1 1 1 1
#2 4 2 11 2 2 2 3
#3 5 3 6 3 3 NA 0
#4 6 4 10 NA 4 NA 1
#5 0 NA 3 NA 5 NA NA
#6 1 NA 1 NA 6 NA NA
#7 NA NA 1 NA 7 NA NA
#8 NA NA 2 NA NA NA NA
#9 NA NA 3 NA NA NA NA
我正在尝试标准化 table timeseries
中列的开始日期,以便每个列都根据我在另一个 table StartEnd
中的预定义值开始. timeseries
中的 datetime
与此问题中的所有日期值一样采用 POSIXct 格式。
我如何创建一个数据框,其中每列的第一行都以 Start
处的值开头,同时还删除 End
处的 0 个值?这是在对堆叠数据集进行 spread() 之后:
timeseries <- spread(timeseries, ID, Count , fill = "0")
我研究过过滤器,但我不确定 dplyr 是否适合这里。我认为某种功能可以解决,但以我有限的知识,我不知道在这种情况下一个人的结构会是什么样子。 Jfyi 我是自学 R 的,除了一些 Coursera 课程外,没有接受过正规的编码教育。
timeseries
:
datetime ID1 ID2 ID3 ID4 ID5 ID6 ID7
1 01/01/19 00:00:00 0 0 7 1 1 0 0
2 01/01/19 01:00:00 0 0 11 2 2 0 0
3 01/01/19 02:00:00 0 0 6 3 3 0 0
4 01/01/19 03:00:00 3 0 10 0 4 0 0
5 01/01/19 04:00:00 4 0 3 0 5 0 0
6 01/01/19 06:00:00 5 1 1 0 6 0 1
7 01/01/19 07:00:00 6 2 1 0 7 0 3
8 01/01/19 09:00:00 0 3 2 0 0 1 0
9 01/01/19 10:00:00 1 4 3 0 0 2 1
StartEnd
:
SomeID Start End
ID1 01/01/19 03:00:00 01/01/19 10:00:00
ID2 01/01/19 06:00:00 01/01/19 10:00:00
ID3 01/01/19 00:00:00 01/01/19 10:00:00
ID4 01/01/19 00:00:00 01/01/19 02:00:00
ID5 01/01/19 00:00:00 01/01/19 07:00:00
ID6 01/01/19 09:00:00 01/01/19 10:00:00
ID7 01/01/19 06:00:00 01/01/19 10:00:00
预期输出:
ID1 ID2 ID3 ID4 ID5 ID6 ID7
1 3 1 7 1 1 1 1
2 4 2 11 2 2 2 3
3 5 3 6 3 3 0
4 6 4 10 4 1
5 0 3 5
6 1 1 6
7 1 7
8 2
9 3
我们可以得到 timeseries
的长格式,将其与 StartEnd
数据框连接,将日期时间列转换为 POSIXct
格式,filter
[=] 之间的值15=] 和 End
并以宽格式获取数据。
library(dplyr)
library(tidyr)
timeseries %>%
pivot_longer(cols = -datetime, names_to = 'SomeID') %>%
left_join(StartEnd, by = 'SomeID') %>%
mutate_at(vars(datetime, Start, End), lubridate::dmy_hms) %>%
filter(datetime >= Start & datetime <= End) %>%
select(SomeID, value) %>%
group_by(SomeID) %>%
mutate(row = row_number()) %>%
pivot_wider(names_from = SomeID, values_from = value) %>%
select(-row) %>%
select(paste0("ID", 1:7))
# A tibble: 9 x 7
# ID1 ID2 ID3 ID4 ID5 ID6 ID7
# <int> <int> <int> <int> <int> <int> <int>
#1 3 1 7 1 1 1 1
#2 4 2 11 2 2 2 3
#3 5 3 6 3 3 NA 0
#4 6 4 10 NA 4 NA 1
#5 0 NA 3 NA 5 NA NA
#6 1 NA 1 NA 6 NA NA
#7 NA NA 1 NA 7 NA NA
#8 NA NA 2 NA NA NA NA
#9 NA NA 3 NA NA NA NA