【问题标题】:How do I extract dates based on values of columns of a time series?如何根据时间序列列的值提取日期?
【发布时间】:2020-03-02 08:44:53
【问题描述】:

假设我有:

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])

【问题讨论】:

  • 数据是 xts 对象重要吗?
  • 一排可以有多个1吗?
  • 我的实际数据来自 getSymbols()。这就是它采用这种格式的原因。我想我可以先将其转换为数据框或其他东西。
  • 是的苏仁可以有

标签: r loops xts


【解决方案1】:

如果对于特定行有多个 1,并且您只想为该行返回一次索引,我们可以使用 rowSums 并将 index 子集化

zoo::index(data)[rowSums(data == 1) > 0]
#[1] "1970-01-02" "1970-01-03" "1970-01-04" "1970-01-05"

如果我们想要每个 1 的索引值,我们可以使用 whicharr.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

【讨论】:

  • 谢谢。有没有办法获取与每个日期关联的列名?
【解决方案2】:

从您原来的 data 对象开始,您可以先创建一个 tibble,然后将其融化以获得您想要的格式:

library(tidyverse)

as_tibble(data) %>% 
  mutate(time = time(data)) %>% 
  gather("group", "value", -time) %>% 
  filter(value == 1) %>% 
  select(group, time)

【讨论】:

    【解决方案3】:

    使用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,则会给出错误的结果。尝试改用 A
    • 是的,是的。我相信它现在已经修复了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多