Найти значение, наиболее близкое по времени к другому - PullRequest
1 голос
/ 13 мая 2019

У меня есть фрейм данных, который состоит из событий, связанных между собой кодом. Каждое из этих событий имеет счет, дату и время. Я хотел бы для данного кода, чтобы найти счетчик, который является ближайшим к данной дате и времени. Например, с этим фреймом данных:

x.df <- structure(list(id = 1:20, code = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), count = c(2L, 
3L, 5L, 7L, 8L, 1L, 2L, 7L, 9L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 4L, 
4L, 8L, 8L), date = structure(c(1L, 1L, 2L, 2L, 3L, 4L, 4L, 4L, 
5L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 9L, 9L), .Label = c("2019-01-01", 
"2019-01-02", "2019-01-03", "2019-02-11", "2019-02-12", "2019-04-22", 
"2019-04-23", "2019-04-24", "2019-04-25"), class = "factor"), 
    time = structure(c(11L, 12L, 10L, 13L, 14L, 1L, 2L, 5L, 7L, 
    17L, 19L, 2L, 3L, 9L, 18L, 4L, 6L, 8L, 15L, 16L), .Label = c("01:01:01", 
    "02:01:02", "02:11:02", "03:01:03", "07:01:07", "09:01:04", 
    "09:01:09", "10:01:04", "12:01:02", "12:10:01", "12:12:12", 
    "12:34:23", "13:15:30", "14:19:23", "18:01:08", "19:01:08", 
    "22:02:12", "23:01:03", "23:02:12"), class = "factor")), class = "data.frame", row.names = c(NA, 
-20L))

Я бы хотел функцию

findcount(code,date,time)

так

findcount(1,"2019-01-02","12:00:00") = 5
findcount(2,"2019-02-02","14:10:23") = 1
findcount(3,"2019-04-29","16:10:00") = 8 

Я попытался установить подмножество данных; отсортировать данные, а затем рассчитать разницу во времени, но это не работает. Кроме того, может быть более эффективный способ выполнения такой операции, чем я думаю. Благодаря.

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

Я написал функцию, которая работает для ваших примеров. Во-первых, я создал столбец в вашем фрейме данных, который объединяет даты и время:

# Create a column that combines the date and time into a single date object
x.df$DateAndTime <- as.POSIXlt(paste(x.df$date, x.df$time))

Затем с помощью следующей функции:

findcount <- function(code, date, time, x.df){

   # Subset the dataframe to include only dates for the current code
   subset <- x.df[x.df$code == code, ]

   # Create a date and time object for the input date and time
   currentDateAndTime <- as.POSIXlt(paste(date, time))

   # Calculate the absolute difference between every date and the current date
   differences <- abs(as.numeric(subset$DateAndTime - currentDateAndTime))

   return(subset$count[which.min(differences)])
}

Я могу быстро определить количество для данного кода, которые соответствуют ближайшей дате и времени:

findcount(1,"2019-01-02","12:00:00", x.df) = 5
findcount(2,"2019-02-02","14:10:23", x.df) = 1
findcount(3,"2019-04-29","16:10:00", x.df) = 8

Обратите внимание, что формат для объединения даты и времени в один объект довольно специфичен ( см. Это описание ), но, к счастью, вы использовали формат, который работал бы без изменений.

1 голос
/ 13 мая 2019

Вы можете использовать функцию ymd_hms() из library(lubridate) и вычислять разницу между двумя датами.

Пример:

example_code = 1
example_date = "2019-01-02"
example_time = "12:00:00"

x.df %>% 
  filter(code == example_code) %>% 
  mutate(hours = paste(date, time) %>% ymd_hms()) %>% 
  mutate(diff = abs(hours - ymd_hms(paste(example_date, example_time)))) %>% 
  arrange(diff) %>% print() %>%

#   id code count       date     time               hours            diff
# 1  3    1     5 2019-01-02 12:10:01 2019-01-02 12:10:01   10.01667 mins
# 2  4    1     7 2019-01-02 13:15:30 2019-01-02 13:15:30   75.50000 mins
# 3  2    1     3 2019-01-01 12:34:23 2019-01-01 12:34:23 1405.61667 mins
# 4  1    1     2 2019-01-01 12:12:12 2019-01-01 12:12:12 1427.80000 mins
# 5  5    1     8 2019-01-03 14:19:23 2019-01-03 14:19:23 1579.38333 mins

  .$count %>% 
  first()

# [1] 5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...