如何根据时间序列的列值提取日期?
How do I extract dates based on values of columns of a time series?
假设我有:
A <- c(1,0,0,0)
B <- c(0,1,0,0)
C <- c(0,0,1,0)
D <- c(0,0,0,1)
data <- xts(cbind(A,B,C,D),order.by = as.Date(1:4))
然后我得到...
A B C D
1970-01-02 1 0 0 0
1970-01-03 0 1 0 0
1970-01-04 0 0 1 0
1970-01-05 0 0 0 1
我想提取值为 1 的每一列的日期。
所以我想看到这样的东西...
A "1970-01-02"
B "1970-01-03"
C "1970-01-04"
D "1970-01-05"
这是获取答案的手动方式。所以我基本上想要 运行 一个可以做到这一点的循环...
index(data$A[data$A==1])
index(data$B[data$B==1])
index(data$C[data$C==1])
index(data$D[data$D==1])
从您的原始 data
对象开始,您可以先创建一个 tibble,然后将其熔化以获得您想要的格式:
library(tidyverse)
as_tibble(data) %>%
mutate(time = time(data)) %>%
gather("group", "value", -time) %>%
filter(value == 1) %>%
select(group, time)
使用 sapply
,我返回行中有 1
的行名称。如果连续有多个 1
,这应该有效。
one_days <- as.Date(unlist(
sapply(1:ncol(data),
function(x) time(data)[which(data[, x] == 1)])))
# "1970-01-02" "1970-01-03" "1970-01-04" "1970-01-05"
如果您还需要行名称。
rown <- unlist(sapply(1 : ncol(data), function(x) rep(colnames(data)[x], sum(data[, x]))))
names(one_days) <- rown
# A B C D
# "1970-01-02" "1970-01-03" "1970-01-04" "1970-01-05"
测试多个 1
A <- c(1,1,0,0)
one_days <- as.Date(unlist(
sapply(1:ncol(data),
function(x) time(data)[which(data[, x] == 1)])))
rown <- unlist(sapply(1 : ncol(data), function(x) rep(colnames(data)[x], sum(data[, x]))))
names(one_days) <- rown
one_days
# A A B C D
#"1970-01-02" "1970-01-03" "1970-01-03" "1970-01-04" "1970-01-05"
如果特定行有多个 1,并且您只想为该行 return 索引一次,我们可以使用 rowSums
并对 index
[=18 进行子集化=]
zoo::index(data)[rowSums(data == 1) > 0]
#[1] "1970-01-02" "1970-01-03" "1970-01-04" "1970-01-05"
如果我们想要每个 1 的索引值,我们可以使用 which
和 arr.ind = TRUE
zoo::index(data)[which(data == 1, arr.ind = TRUE)[, 1]]
要同时获取列名和索引,我们可以重用 which
中的矩阵
mat <- which(data == 1, arr.ind = TRUE)
data.frame(index = zoo::index(data)[mat[, 1]], column = colnames(data)[mat[,2]])
# index column
#1 1970-01-02 A
#2 1970-01-03 B
#3 1970-01-04 C
#4 1970-01-05 D
假设我有:
A <- c(1,0,0,0)
B <- c(0,1,0,0)
C <- c(0,0,1,0)
D <- c(0,0,0,1)
data <- xts(cbind(A,B,C,D),order.by = as.Date(1:4))
然后我得到...
A B C D
1970-01-02 1 0 0 0
1970-01-03 0 1 0 0
1970-01-04 0 0 1 0
1970-01-05 0 0 0 1
我想提取值为 1 的每一列的日期。 所以我想看到这样的东西...
A "1970-01-02"
B "1970-01-03"
C "1970-01-04"
D "1970-01-05"
这是获取答案的手动方式。所以我基本上想要 运行 一个可以做到这一点的循环...
index(data$A[data$A==1])
index(data$B[data$B==1])
index(data$C[data$C==1])
index(data$D[data$D==1])
从您的原始 data
对象开始,您可以先创建一个 tibble,然后将其熔化以获得您想要的格式:
library(tidyverse)
as_tibble(data) %>%
mutate(time = time(data)) %>%
gather("group", "value", -time) %>%
filter(value == 1) %>%
select(group, time)
使用 sapply
,我返回行中有 1
的行名称。如果连续有多个 1
,这应该有效。
one_days <- as.Date(unlist(
sapply(1:ncol(data),
function(x) time(data)[which(data[, x] == 1)])))
# "1970-01-02" "1970-01-03" "1970-01-04" "1970-01-05"
如果您还需要行名称。
rown <- unlist(sapply(1 : ncol(data), function(x) rep(colnames(data)[x], sum(data[, x]))))
names(one_days) <- rown
# A B C D
# "1970-01-02" "1970-01-03" "1970-01-04" "1970-01-05"
测试多个 1
A <- c(1,1,0,0)
one_days <- as.Date(unlist(
sapply(1:ncol(data),
function(x) time(data)[which(data[, x] == 1)])))
rown <- unlist(sapply(1 : ncol(data), function(x) rep(colnames(data)[x], sum(data[, x]))))
names(one_days) <- rown
one_days
# A A B C D
#"1970-01-02" "1970-01-03" "1970-01-03" "1970-01-04" "1970-01-05"
如果特定行有多个 1,并且您只想为该行 return 索引一次,我们可以使用 rowSums
并对 index
[=18 进行子集化=]
zoo::index(data)[rowSums(data == 1) > 0]
#[1] "1970-01-02" "1970-01-03" "1970-01-04" "1970-01-05"
如果我们想要每个 1 的索引值,我们可以使用 which
和 arr.ind = TRUE
zoo::index(data)[which(data == 1, arr.ind = TRUE)[, 1]]
要同时获取列名和索引,我们可以重用 which
mat <- which(data == 1, arr.ind = TRUE)
data.frame(index = zoo::index(data)[mat[, 1]], column = colnames(data)[mat[,2]])
# index column
#1 1970-01-02 A
#2 1970-01-03 B
#3 1970-01-04 C
#4 1970-01-05 D