Отфильтруйте последние n наблюдений в метке времени R

#r #datetime #dplyr

#r #datetime #dplyr

Вопрос:

Я новичок в R, и у меня простой вопрос.

У меня есть фрейм данных, в котором у меня есть столбец с меткой времени и различные другие функции. Столбец метки времени состоит из 31 дня, и мне нужно получить последние n дней (скажем, 16) метки времени.

Предполагая 31 день, затем он предоставит мне наблюдения за последние 16 дней (с 16 по 31 октября). Я знаю, как это сделать в Python, но я понятия не имею, как это сделать в R.

Пример df:

 f1 f2 f3 timestamp
1  2  3  2020-10-02 14:36:03
2  3  5  2020-10-03 14:26:03
1  2  3  2020-10-05 14:36:03
2  3  5  2020-10-05 14:26:03
1  2  3  2020-10-07 14:36:03
2  3  5  2020-10-10 14:26:03
1  2  3  2020-10-12 14:36:03
2  3  5  2020-10-13 14:26:03
1  2  3  2020-10-15 14:36:03
2  3  5  2020-10-16 14:26:03
1  2  3  2020-10-22 14:36:03
2  3  5  2020-10-25 14:26:03
1  2  3  2020-10-26 14:36:03
2  3  5  2020-10-31 14:26:03

 

Как должен выглядеть результат:

 f1 f2 f3 timestamp
2  3  5  2020-10-16 14:26:03
1  2  3  2020-10-22 14:36:03
2  3  5  2020-10-25 14:26:03
1  2  3  2020-10-26 14:36:03
2  3  5  2020-10-31 14:26:03
 

Время в метке времени отличается для каждого наблюдения, и приведенный выше кадр приведен только для иллюстрации.
Любая помощь будет оценена.

Обновление для устранения путаницы:

Я не могу использовать функцию tail(), как в исходном фрейме данных, в день несколько значений. Извиняюсь за то, что не прояснил.

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

1. Попробуйте использовать dput() с вашим data.frame и опубликовать результат. Затем можно напрямую попробовать с вашими примерами данных

2. tail Функция tail(df, n) вернет последние n строки фрейма данных. Например. last8 <- tail(mtcars, 8)

3. @SteveM Я не могу использовать функцию tail, потому что существует несколько значений в день. есть ли какая-либо альтернатива.

Ответ №1:

Может быть, вам нужно lubridate в subset

 library(lubridate)
subset(
  df,
  day(timestamp) >= days_in_month(timestamp) - 15
)
 

или dplyr каким-либо образом

 df %>%
  filter(between(day(timestamp), days_in_month(timestamp) - 15, days_in_month(timestamp)))
 

что дает

    f1 f2 f3           timestamp
10  2  3  5 2020-10-16 14:26:03
11  1  2  3 2020-10-22 14:36:03
12  2  3  5 2020-10-25 14:26:03
13  1  2  3 2020-10-26 14:36:03
14  2  3  5 2020-10-31 14:26:03
 

Данные

 > dput(df)
structure(list(f1 = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
1L, 2L, 1L, 2L), f2 = c(2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L,
2L, 3L, 2L, 3L), f3 = c(3L, 5L, 3L, 5L, 3L, 5L, 3L, 5L, 3L, 5L,
3L, 5L, 3L, 5L), timestamp = structure(c(1601642163, 1601727963,
1601901363, 1601900763, 1602074163, 1602332763, 1602506163, 1602591963,
1602765363, 1602851163, 1603370163, 1603632363, 1603719363, 1604150763
), class = c("POSIXct", "POSIXt"), tzone = "")), row.names = c(NA,
-14L), class = "data.frame")
 

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

1. Работает идеально. Я не знал об этом методе. Подробнее об этом.

2. @SyedAhmed Я упростил свой ответ, чтобы вы могли его проверить

Ответ №2:

Если вам нужно сначала упорядочить свой фрейм данных, затем использовать order , после чего вы можете просто использовать unique with tail для получения дат, а затем просто отфильтровать свой фрейм данных. Я предполагаю, что с меткой времени вы имеете в виду POSIXct класс в R, затем попробуйте

 data <- data.frame(
  f1 = c(1,2,1,2,1,2),
  timestamp = as.POSIXct(c(
    "2020-10-02 14:36:03",
    "2020-10-03 14:26:03",
    "2020-10-05 14:36:04",
    "2020-10-05 14:36:04",
    "2020-10-05 14:36:04",
    "2020-10-05 14:36:05"
  ))
)
data_ordered <- data[order(as.Date(data$timestamp)),]
dates <- tail(unique(data_ordered$timestamp), 2)

data_ordered[data_ordered$timestamp %in% dates, ]
 

без заказа вы, конечно, можете напрямую обращаться tail() к своему фрейму данных.

Альтернатива:

Приведенная выше версия является базовой R, вы также могли бы решить свою проблему немного проще, используя tidyverse или data.table

Альтернатива 1: tidyverse

 library(dplyr)
library(tibble)
data <- as_tibble(data)
data %>% filter(timestamp %in% dates)
 

Альтернатива 2: data.table

 library(data.table)
data <- as.data.table(data)
data[timestamp %in% dates]
 

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

1. Привет @Thomas, я не могу использовать функцию tail, потому что в день есть несколько значений. есть ли какая-либо альтернатива.