Перекодирование данных временных рядов для создания времени 0 для каждого человека

#r #dplyr #tidyr

#r #dplyr #tidyr

Вопрос:

Я пытаюсь перекодировать некоторые данные, собранные каждые 2 часа, таким образом, чтобы я находил начальную точку для каждого идентификатора (т. Е. Когда obs не равен нулю, т. Е. Есть Данные для этого момента времени), назовите это время 0, а затем для каждого последующего момента времени вызывается 2, 4, 6 и т.д.

Например,

     ID <- c("f1", "f1", "f1", "f1", "f2", "f2", "f2", "f2", "f3", "f3", "f3", "f3")
    time <- rep(c(66, 68, 70, 72), 3)
    obs <- c(1, 3, 5, 6, 0, 0, 3, 4, 0, 1, 3, 3)
    new.time <- c(0, 2, 4, 6, NA, NA, 0, 2, NA, 0, 2, 4)
    data <- as.data.frame(cbind(ID, time, obs, new.time))
  

Надеюсь, этот фрейм данных работает

у меня есть идентификатор, время и obs, но я хочу создать «новое время» — любая помощь приветствуется, особенно решение dplyr

Комментарии:

1. ок, изменились на фрейм данных

Ответ №1:

1) Мы определяем data как data.frame, а не как матрицу в примечании в конце, а затем используем ave для установки new.time :

Пакеты не используются.

 make_no <- function(obs) c(rep(NA, sum(obs == 0)), seq(0, length = sum(obs != 0), by = 2))
transform(data, new.time = ave(obs, ID, FUN = make_no))
  

предоставление:

    ID time obs new.time
1  f1   66   1        0
2  f1   68   3        2
3  f1   70   5        4
4  f1   72   6        6
5  f2   66   0       NA
6  f2   68   0       NA
7  f2   70   3        0
8  f2   72   4        2
9  f3   66   0       NA
10 f3   68   1        0
11 f3   70   3        2
12 f3   72   3        4
  

2) или с помощью dplyr:

 data %>%
  group_by(ID) %>%
  mutate(new.time = make_no(obs)) %>%
  ungroup
  

Примечание

 ID <- c("f1", "f1", "f1", "f1", "f2", "f2", "f2", "f2", "f3", "f3", "f3", "f3")
time <- rep(c(66, 68, 70, 72), 3)
obs <- c(1, 3, 5, 6, 0, 0, 3, 4, 0, 1, 3, 3)
data <- data.frame(ID, time, obs)
  

Комментарии:

1. спасибо, это работает с практическим набором данных, но не с фактическим набором данных… я просто получаю NAs….

2. Обратите внимание, что в коде, представленном в вопросе, есть ошибка. as.data.frame(cbind(...)) создает символьную матрицу, а затем преобразует ее во фрейм данных. В результате столбцы, которые должны быть числовыми, являются коэффициентами. Смотрите Примечание в конце ответа для правильного способа сделать это. Кроме этого, вам нужно либо выяснить, в чем разница между тем, что у вас есть, и тем, что вы представили, и исправить вопрос, поскольку мы не можем знать, что у вас есть, но не показали.

Ответ №2:

Мы можем создать пользовательскую функцию и применить ее к группе, т.е.

 f1 <- function(x) {
    x1 <- length(x[x != 0])
    i1 <- seq(0, length.out = x1, by = 2)
    i2 <- c(rep(NA, (length(x) - x1)),i1)
    return(i2)
}

#Using `dplyr` to apply it,
library(dplyr)

df %>% 
 group_by(ID) %>% 
 mutate(new = f1(obs))
  

что дает,

 # A tibble: 12 x 4
# Groups:   ID [3]
   ID    time  obs     new
   <fct> <fct> <fct> <dbl>
 1 f1    66    1         0
 2 f1    68    3         2
 3 f1    70    5         4
 4 f1    72    6         6
 5 f2    66    0        NA
 6 f2    68    0        NA
 7 f2    70    3         0
 8 f2    72    4         2
 9 f3    66    0        NA
10 f3    68    1         0
11 f3    70    3         2
12 f3    72    3         4