R: Получение оценок участников из другой таблицы на основе дат рождения - PullRequest
0 голосов
/ 09 марта 2020

У меня есть две таблицы: одна с участниками и одна с кодировкой баллов по датам рождения. Таблица результатов выглядит следующим образом:

score_table

Key        |  Value
--------------------
01/01/1900 |  15
01/01/1940 |  25
01/01/1950 |  30

Все участники с датами рождения в период с 01.01.1900 по 01.01.1940 должны получить 15 баллов. Участники, родившиеся между 01.01.1940 и 01 / 01/1950 следует набрать 25 баллов, и т. Д. c.

Таблица моих участников выглядит следующим образом:

participant_table

BirthDate    |   Gender
-----------------------
05/05/1930   |   M
02/07/1954   |   V
01/11/1941   |   U

Я хотел бы добавить оценку, чтобы получить результат table:

BirthDate    |   Gender   |   Score
------------------------------------
05/05/1930   |   M        |   15
02/07/1954   |   V        |   30
01/11/1941   |   U        |   25

Я построил несколько решений для похожих задач, когда точные значения находятся в таблице оценок (с помощью dplyr :: left_join или base :: match) или для чисел, которые можно округлить до другого значения. Здесь интервалы нерегулярны, а даты произвольны.

Я знаю, что могу построить решение, перебирая таблицу оценок, используя этот метод:

as.Date("05/05/1930", format="%d/%m/%Y) < as.Date("01/01/1900", format="%d/%m/%Y)

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

Может быть, я могу создать какие-то бины из кадра данных, например:

Bin 1           | Bin 2           | Bin 3
Date 1 : Date 2 | Date 2 : Date 3 | Date 3 : inf

Но я пока не понимаю, как , Кто-нибудь видит эффективный способ создания таких бинов из кадра данных, чтобы я мог эффективно получать оценки из этой таблицы?

MRE:

Таблица результатов:

structure(list(key=c("1/1/1900", "2/1/2013", "2/1/2014","2/1/2015", "4/1/2016", "4/1/2017"), value=c(65,65,67,67,67,68)), row.names=1:6, class="data.frame")

Файл участника:

structure(list(birthDate=c("10/10/1968", "6/5/2015","10/10/2017"), Gender=c("M", "U", "F")), row.names=1:3, class="data.frame")

Файл цели:

structure(list(birthDate=c("10/10/1968", "6/5/2015","10/10/2017"), Gender=c("M", "U", "F"), Score = c(65,67,68)), row.names=1:3, class="data.frame")

Ответы [ 2 ]

0 голосов
/ 18 марта 2020

Я нашел очень простое решение, использующее только арифметику c.

Чтобы получить оценку, я проверяю, сколько чисел заменено на дату ввода:

rownum <- sum(as.Date(input_date, format="%d/%m/%Y") > 
              as.Date(score_table$Key, format="%d/%m/%Y"))

Затем соответствующий ключ можно найти с помощью:

score <- score_table[["Value"]][rownum]

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

0 голосов
/ 09 марта 2020

Вот подход, использующий lag() вместе с sqldf:

score_table$Key2 <- as.Date(lead(score_table$Key), format="%d/%m/%Y")
score_table$Key <- as.Date(score_table$Key, format="%d/%m/%Y")
names(score_table) <- c("Date1", "Value", "Date2")
participant_table$BirthDate <- as.Date(participant_table$BirthDate, format="%d/%m/%Y")
sql <- "SELECT p.BirthDate, p.Gender, s.Value AS Score
        FROM participant_table p
        INNER JOIN score_table s
            ON (p.BirthDate >= s.Date1 OR s.Date1 IS NULL) AND
               (p.BirthDate < s.Date2 OR s.Date2 IS NULL)"
participant_table <- sqldf(sql)

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

У меня на самом деле нет R, работающего локально в данный момент, но вот демонстрационная ссылка на SQLite, показывающая, что SQL logi c работает правильно:

screen capture of demo link below

Демо

...