Как создать подмножество нескольких диапазонов дат в R - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть фрейм данных с датами и числами под названием 'df'. У меня есть еще один фрейм данных с датами начала и окончания, который называется date_ranges.

Моя цель - отфильтровать / установить поднабор df, чтобы он отображался только для дат начала / окончания в каждой строке столбца date_ranges. Вот мой код:


    df_date <- as.Date((as.Date('2010-01-01'):as.Date('2010-04-30')))
    df_numbers <- c(1:120)
    df <- data.frame(df_date, df_numbers)


    start_dates <- as.Date(c("2010-01-06", "2010-02-01", '2010-04-15'))
    end_dates <- as.Date(c("2010-01-23", "2010-02-06", '2010-04-29'))
    date_ranges <- data.frame(start_dates, end_dates)

    # Attempting to filter df by start and end dates
    for (i in range(date_ranges$start_dates)){
      for (j in range(date_ranges$end_dates)){
        print (
          df %>%
          filter(between(df_date, i, j)))
      }

    }

Первый и третий результат вложенности для l oop - это то, что я хочу, но не второй результат. Первый и третий дают мне даты и значения для df между их соответствующими строками, но второй результат - диапазон от самой ранней даты до самой последней даты. Как я могу исправить это l oop, чтобы исключить второй результат?

Ответы [ 3 ]

2 голосов
/ 23 апреля 2020
Подход

A tidyverse может заключаться в создании последовательности между start и end_dates и соединении с df, чтобы сохранить только даты, которые l ie в диапазоне.

library(dplyr)

date_ranges %>%
  mutate(df_date = purrr::map2(start_dates, end_dates, seq, "day")) %>%
  tidyr::unnest(df_date) %>%
  select(-start_dates, -end_dates) %>%
  left_join(df, by = 'df_date')

# A tibble: 39 x 2
#   df_date    df_numbers
#   <date>          <int>
# 1 2010-01-06          6
# 2 2010-01-07          7
# 3 2010-01-08          8
# 4 2010-01-09          9
# 5 2010-01-10         10
# 6 2010-01-11         11
# 7 2010-01-12         12
# 8 2010-01-13         13
# 9 2010-01-14         14
#10 2010-01-15         15
# … with 29 more rows
1 голос
/ 23 апреля 2020

Вы можете попробовать пройтись по индексу

for (i in seq_along(date_ranges$start_dates)){
    print (
      df %>%
        filter(between(df_date, date_ranges$start_dates[i], date_ranges$end_dates[i])))
}

0 голосов
/ 23 апреля 2020

Базовый раствор R:

# Your data creation can be simplified: 
df <- data.frame(df_date = seq.Date(as.Date('2010-01-01', "%Y-%m-%d"), as.Date('2010-04-30', "%Y-%m-%d"),
                                    by = 1), df_numbers = c(1:120))

# Store start and end date vectors to filter the data.frame: 
start_dates <- as.Date(c("2010-01-06", "2010-02-01", '2010-04-15'))
end_dates <- as.Date(c("2010-01-23", "2010-02-06", '2010-04-29'))

# Subset the data to extract records with matching dates: df => stdout (Console
df[df$df_date %in% c(start_dates, end_dates),]
...