Как извлечь даты на основе значений столбцов временного ряда? - PullRequest
3 голосов
/ 06 ноября 2019

Предположим, у меня есть:

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

Ответы [ 3 ]

1 голос
/ 06 ноября 2019

Если для конкретной строки есть несколько единиц, и вы хотите вернуть индекс только один раз для этой строки, мы можем использовать rowSums и подмножество index

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
0 голосов
/ 06 ноября 2019

Используя 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"
0 голосов
/ 06 ноября 2019

Начиная с исходного объекта data, вы можете сначала создать тиббл, а затем расплавить его, чтобы получить нужный формат:

library(tidyverse)

as_tibble(data) %>% 
  mutate(time = time(data)) %>% 
  gather("group", "value", -time) %>% 
  filter(value == 1) %>% 
  select(group, time)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...