#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, потому что в день есть несколько значений. есть ли какая-либо альтернатива.