Поиск между фреймами данных.Если совпадение существует, возвращаемое количество, максимальное и минимальное значение - PullRequest
0 голосов
/ 14 мая 2018

Я новичок в R, и кажется, что решение, которое я нашел для моей проблемы, занимает слишком много времени.

У меня есть 2 кадра:

 UniqueID  colA colB
 1          x     y
 2          x     y
 3          x     y
 4          x     y

И

UniqueID   category   date
 1           a        d1
 1           a        d2
 1           b        d3
 2           c        d4
 3           a        d5
 3           a        d6

Я хочу получить фрейм данных, который позже будет добавлен к первому, с чем-то вроде (при условии d1

 UniqueID    totaloccurrences  occurrencescatA MindatecatA MaxdatecatA
 1                  3                 2             d1          d2
 2                  1                 0             0            0
 3                  2                 2             d5           d6

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

Лучшее, что я мог сделать, это использовать цикл for:

iteractions <- nrow(A) for (i in 1:iteractions) { compiled[i, "ID"] <- A[i, "UniqueID"] compiled[i, "totaloccurrences"] <- length(B$UniqueID[B$UniqueID ==compiled[i, "ID"]]) compiled[i, "occurrencescatA"] <- length(B$UniqueID[B$UniqueID ==compiled[i, "ID"] & B$category == "d1"] if (compiled[i, "occurencescatA"] != 0) { compiled[i, "MindatecatA"] <- min(B$date[B$category =="a" & B$UniqueID ==compiled[i, "ID"]])

...

И так до максимальной даты, затем повторите для каждой категории.

Проблема в том, что кадры данных огромны, и это занимает очень много времени. Я считаю, что мне не хватает изящества, но любая помощь здесь будет признательна!

1 Ответ

0 голосов
/ 15 мая 2018

Вот подход tidyverse:

library(tidyverse);
printDate <- function(x) format(x, "%d-%m-%Y");
left_join(
    df2 %>% mutate(date = as.Date(date, format = "%d-%m-%Y")),
    df1) %>%
    group_by(UniqueID) %>%
    summarise(
        totaloccurrences = n(),
        occurrencescatA = sum(category == "a"),
        MindatecatA = ifelse(occurrencescatA > 0, printDate(min(date[category == "a"])), "0"),
        MaxdatecatA = ifelse(occurrencescatA > 0, printDate(max(date[category == "a"])), "0"))
## A tibble: 3 x 5
#  UniqueID totaloccurrences occurrencescatA MindatecatA MaxdatecatA
#     <int>            <int>           <int> <chr>       <chr>
#1        1                3               2 01-05-2018  02-05-2018
#2        2                1               0 0           0
#3        3                2               2 05-05-2018  06-05-2018

Объяснение: Выполните левое объединение df1 и df2, сгруппируйте записи по UniqueID и верните итоговые количества, используя summarise.

Обратите внимание, что я сгенерировал несколько примеров date s для иллюстрации.


Пример данных

df1 <- read.table(text =
    "UniqueID  colA colB
 1          x     y
 2          x     y
 3          x     y
 4          x     y", header = T)


df2 <- read.table(text =
    "UniqueID   category   date
 1           a        01-05-2018
 1           a        02-05-2018
 1           b        03-05-2018
 2           c        04-05-2018
 3           a        05-05-2018
 3           a        06-05-2018", header = T)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...