Повторяющиеся строки, чтобы все столбцы оставались одинаковыми, но один столбец последовательно увеличивался - PullRequest
0 голосов
/ 07 января 2019

Работа в R Моя текущая таблица выглядит так:

C1    C2                          C3
1     2011-02-01 04:30:00         4
2     2011-02-01 04:45:00         3
3     2011-02-01 05:00:00         5
4     2011-02-01 05:15:00         6

Я хочу, чтобы это выглядело так:

C1    C2                          C3       C4
1     2011-02-01 04:30:00         4        2011-02-01 04:30:00
2     2011-02-01 04:30:00         4        2011-02-01 04:35:00
3     2011-02-01 04:30:00         4        2011-02-01 04:40:00
4     2011-02-01 04:45:00         3        2011-02-01 04:45:00
5     2011-02-01 04:45:00         3        2011-02-01 04:50:00 
6     2011-02-01 04:45:00         3        2011-02-01 04:55:00
7     2011-02-01 05:00:00         5        2011-02-01 05:00:00
8     2011-02-01 05:00:00         5        2011-02-01 05:05:00

и т.д.. и т.д., в основном, просто нужно создать еще один столбец, который увеличивается с интервалом в пять минут, но совпадает с интервалами в C2. Я думал о чем-то похожем на функцию rep (), но это означало бы, что интервалы в C2 всегда постоянны, чего не может быть. Я действительно ищу что-то, что будет делать пятиминутные интервалы в зависимости от того, какие интервалы в C2.

Любая помощь или отзывы по этому вопросу будет принята с благодарностью. спасибо

Ответы [ 4 ]

0 голосов
/ 07 января 2019
library(lubridate)

Вы можете использовать этот пакет библиотеки. Конвертируйте df [C2] в качестве даты или времени, используя apply() или напрямую назначая это время даты. как только он будет конвертирован, используйте

df[C4] <- ymd_hms(df[C2]) + min(5) или df[C4] <- ymd_hms(df[C2]) + seconds(300)

0 голосов
/ 07 января 2019

Мы можем создать последовательность из 5-минутных интервалов между min и max значениями C2, а затем выполнить left_join для df и заполнить пропущенные значения предыдущим значением, используя na.locf из зоопарка.

library(dplyr)
library(zoo)

data.frame(C4 = seq(min(df$C2), max(df$C2), by = "5 min")) %>%
   left_join(transform(df, C4 = C2)) %>%
   na.locf()

#                    C4 C1                  C2 C3
#1  2011-02-01 04:30:00  1 2011-02-01 04:30:00  4
#2  2011-02-01 04:35:00  1 2011-02-01 04:30:00  4
#3  2011-02-01 04:40:00  1 2011-02-01 04:30:00  4
#4  2011-02-01 04:45:00  2 2011-02-01 04:45:00  3
#5  2011-02-01 04:50:00  2 2011-02-01 04:45:00  3
#6  2011-02-01 04:55:00  2 2011-02-01 04:45:00  3
#7  2011-02-01 05:00:00  3 2011-02-01 05:00:00  5
#8  2011-02-01 05:05:00  3 2011-02-01 05:00:00  5
#9  2011-02-01 05:10:00  3 2011-02-01 05:00:00  5
#10 2011-02-01 05:15:00  4 2011-02-01 05:15:00  6
0 голосов
/ 07 января 2019

Другая опция tidyverse с использованием complete,

library(tidyverse)

df %>% 
 mutate(C2 = as.POSIXct(C2, format = '%Y-%m-%d %H:%M:%S'), C4 = C2) %>% 
 complete(C4 = seq(min(C2), max(C2), by = '5 min')) %>% 
 fill(C1, C2, C3)

, что дает,

# A tibble: 10 x 4
   C4                  C1    C2                     C3
   <dttm>              <chr> <dttm>              <int>
 1 2011-02-01 04:30:00 1     2011-02-01 04:30:00     4
 2 2011-02-01 04:35:00 1     2011-02-01 04:30:00     4
 3 2011-02-01 04:40:00 1     2011-02-01 04:30:00     4
 4 2011-02-01 04:45:00 2     2011-02-01 04:45:00     3
 5 2011-02-01 04:50:00 2     2011-02-01 04:45:00     3
 6 2011-02-01 04:55:00 2     2011-02-01 04:45:00     3
 7 2011-02-01 05:00:00 3     2011-02-01 05:00:00     5
 8 2011-02-01 05:05:00 3     2011-02-01 05:00:00     5
 9 2011-02-01 05:10:00 3     2011-02-01 05:00:00     5
10 2011-02-01 05:15:00 4     2011-02-01 05:15:00     6
0 голосов
/ 07 января 2019

Мы можем использовать map2 для создания столбца list, взяв seq значение Datetime преобразованного 'C2' с length, заданного соответствующим элементом 'C3' by 5-минутные интервалы и unnest столбец list

library(tidyverse)
df1 %>% 
  mutate(C4 = map2(lubridate::ymd_hms(C2), C3, ~ seq(.x, length.out = .y, by = '5 min'))) %>% 
  unnest
#  C1                  C2 C3                  C4
#1   1 2011-02-01 04:30:00  4 2011-02-01 04:30:00
#2   1 2011-02-01 04:30:00  4 2011-02-01 04:35:00
#3   1 2011-02-01 04:30:00  4 2011-02-01 04:40:00
#4   1 2011-02-01 04:30:00  4 2011-02-01 04:45:00
#5   2 2011-02-01 04:45:00  3 2011-02-01 04:45:00
#6   2 2011-02-01 04:45:00  3 2011-02-01 04:50:00
#7   2 2011-02-01 04:45:00  3 2011-02-01 04:55:00
#8   3 2011-02-01 05:00:00  5 2011-02-01 05:00:00
#9   3 2011-02-01 05:00:00  5 2011-02-01 05:05:00
#10  3 2011-02-01 05:00:00  5 2011-02-01 05:10:00
#11  3 2011-02-01 05:00:00  5 2011-02-01 05:15:00
#12  3 2011-02-01 05:00:00  5 2011-02-01 05:20:00
#13  4 2011-02-01 05:15:00  6 2011-02-01 05:15:00
#14  4 2011-02-01 05:15:00  6 2011-02-01 05:20:00
#15  4 2011-02-01 05:15:00  6 2011-02-01 05:25:00
#16  4 2011-02-01 05:15:00  6 2011-02-01 05:30:00
#17  4 2011-02-01 05:15:00  6 2011-02-01 05:35:00
#18  4 2011-02-01 05:15:00  6 2011-02-01 05:40:00

Или, используя Map из base R, получите list последовательностей DateTime с той же логикой, что и выше. Разверните исходный набор данных с помощью rep, лицензируя последовательность строк на основе lengths из 'lst1' и создайте новый столбец 'C4'

lst1 <- Map(function(x, y) seq(x, length.out = y, by = '5 min'),
    as.POSIXct(df1$C2), df1$C3)
df2 <- df1[rep(seq_len(nrow(df1)), lengths(lst1)),]
df2$C4 <- do.call(c, lst1)
row.names(df2) <- NULL

Если условие основано на следующем значении 'C2'

df1 %>% 
   mutate(C4 = map2(ymd_hms(C2), lubridate::ymd_hms(lead(C2, default = last(C2))),
        seq, by = '5 min')) %>%
   unnest %>% 
   group_by(C1) %>% 
   slice(-1)
# A tibble: 9 x 4
# Groups:   C1 [3]
#     C1 C2                     C3 C4                 
#  <int> <chr>               <int> <dttm>             
#1     1 2011-02-01 04:30:00     4 2011-02-01 04:35:00
#2     1 2011-02-01 04:30:00     4 2011-02-01 04:40:00
#3     1 2011-02-01 04:30:00     4 2011-02-01 04:45:00
#4     2 2011-02-01 04:45:00     3 2011-02-01 04:50:00
#5     2 2011-02-01 04:45:00     3 2011-02-01 04:55:00
#6     2 2011-02-01 04:45:00     3 2011-02-01 05:00:00
#7     3 2011-02-01 05:00:00     5 2011-02-01 05:05:00
#8     3 2011-02-01 05:00:00     5 2011-02-01 05:10:00
#9     3 2011-02-01 05:00:00     5 2011-02-01 05:15:00

или аналогичный вариант с использованием методов из data.table

library(data.table)
setDT(df1)[, C2 := as.POSIXct(C2)][, C4 := list(Map(seq, 
   MoreArgs = list(by = '5 min'), C2, shift(C2, type = 'lead',
      fill = last(C2))))][, unnest(.SD)][, .SD[-1], by = C1]

данные

df1 <- structure(list(C1 = 1:4, C2 = c("2011-02-01 04:30:00", "2011-02-01 04:45:00", 
"2011-02-01 05:00:00", "2011-02-01 05:15:00"), C3 = c(4L, 3L, 
 5L, 6L)), class = "data.frame", row.names = c(NA, -4L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...