объединение двух наборов данных на основе общего идентификатора и даты в пределах интервала - PullRequest
2 голосов
/ 20 января 2020

У меня есть два набора данных: DF1 - фрейм данных, в котором перечислены главы государств (leader_id) стран (country_code) и интервал их времени в офисе (office_interval). DF2 - кадр данных, в котором каждое наблюдение представляет собой событие, которое имеет идентификатор (идентификатор события) страны (код страны) и дату, когда оно произошло (дата события)

Данные:

library(lubridate)

#Leader DF
leader_id <- c("Adam","Bob","Charlie","Derek", "Edgar")
country_code <- c(1,1,2,2,3)
office_interval <- c(interval(ymd("1900-01-01"), ymd("1905-01-01")), 
                     interval(ymd("1910-01-01"), ymd("1915-01-01")),
                     interval(ymd("1920-01-01"), ymd("1925-01-01")),
                     interval(ymd("1930-01-01"), ymd("1935-01-01")),
                     interval(ymd("1940-01-01"), ymd("1945-01-01")))
DF1 <- data.frame(leader_id, country_code, office_interval)

#Event DF
event_id <- c(1,1,2,3,3)
country_code <- c(1,2,2,1,3)
event_date <- c(as.Date("1901-01-02"), 
                as.Date("1920-01-02"), 
                as.Date("1921-01-02"),
                as.Date("1911-01-02"),
                as.Date("1941-02-02"))
DF2 <- data.frame(event_id, country_code, event_date)

Я хотел бы принять создайте новый столбец в DF2, который будет использовать эти данные из DF1 на основе каждой строки в DF2, которая встречается в пределах office_interval лидеров в той же стране.

DF2 должен выглядеть следующим образом:

  event_id country_code event_date leader_id
1        1            1 1901-01-02      Adam
2        1            2 1920-01-02   Charlie
3        2            2 1921-01-02   Charlie
4        3            1 1911-01-02       Bob
5        3            3 1941-02-02     Edgar

Я пробовал некоторые решения из здесь , но я не могу заставить их работать.

Ответы [ 3 ]

2 голосов
/ 20 января 2020

Вот решение, может быть, может работать для вашей цели

idx <- sapply(1:nrow(DF2), function(k) which(DF2$event_date[k] %within% DF1$office_interval & DF2$country_code[k]%in% DF1$country_code))
DF2$leader_id <- DF1$leader_id[idx]

такое, что

> DF2
  event_id country_code event_date leader_id
1        1            1 1901-01-02      Adam
2        1            2 1920-01-02   Charlie
3        2            2 1921-01-02   Charlie
4        3            1 1911-01-02       Bob
5        3            3 1941-02-02     Edgar
0 голосов
/ 20 января 2020

Мы можем left_join DF2 и DF1 по "country_code" и сохранять записи, которые находятся в пределах интервала времени.

library(dplyr)
library(lubridate)

left_join(DF2, DF1, by = "country_code") %>% 
      filter(event_date %within% office_interval)

#  event_id country_code event_date leader_id                office_interval
#1        1            1 1901-01-02      Adam 1900-01-01 UTC--1905-01-01 UTC
#2        1            2 1920-01-02   Charlie 1920-01-01 UTC--1925-01-01 UTC
#3        2            2 1921-01-02   Charlie 1920-01-01 UTC--1925-01-01 UTC
#4        3            1 1911-01-02       Bob 1910-01-01 UTC--1915-01-01 UTC
#5        3            3 1941-02-02     Edgar 1940-01-01 UTC--1945-01-01 UTC
0 голосов
/ 20 января 2020

Это также должно работать:

# add start and end date
DF1$start_date <- substr(DF1$office_interval, 1, 10)
DF1$end_date <- substr(DF1$office_interval, 17, 26)

# merge dataframes
DF2 <- merge(x = DF2, y = DF1, by.x = "country_code", by.y = "country_code")

# filter for correct times
DF2 <- DF2[(DF2$event_date >= DF2$start_date & DF2$event_date <= DF2$end_date),]

# select columns
DF2[1:4]
...