Условное количество на строку - PullRequest
1 голос
/ 17 января 2020

Я работаю над набором данных со следующими столбцами:

    cik accession            logdate    filedate    
1     3 0000000003-15-000335 2016-02-19 NA        
2     3 0000000003-96-000001 2004-12-28 1996-02-14
3     3 0000350001-16-206023 2016-04-13 NA        
4     3 0000934850-98-001281 2004-12-28 1998-03-02
5     9 0001047469-15-006597 2015-08-06 2015-08-05
6    13 0001156175-14-000006 2014-02-26 NA        
7    14 0000950103-94-003177 2014-12-31 1994-06-30
8    14 0000950103-94-003177 2015-11-30 1994-06-30
9    14 0000950112-94-000770 2016-11-30 1994-03-24
10   18 0000774467-94-000134 2016-11-30 1994-02-22
11   20 0000080255-05-000285 2006-04-17 2005-02-11
12   20 0000893220-03-000038 2016-09-27 2003-01-15
13   20 0000893220-04-000596 2004-10-04 2004-04-01
14   20 0000893220-05-000728 2006-04-17 2005-03-31
15   20 0000893220-06-000686 2015-04-06 2006-03-28
16   20 0000893220-06-001733 2006-08-07 2006-08-07
17   20 0000893220-06-002144 2007-11-27 2006-10-05
18   20 0000893220-06-002635 2007-11-27 2006-12-15
19   20 0000893220-07-000678 2007-11-20 2007-03-09
20   20 0000893220-07-000678 2016-11-17 2007-03-09 

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

  1. То же cik

  2. То же присоединение

  3. Разница между датой регистрации и датой подачи составляет от 0 до 30 дней

Я использовал следующий код для вычисления этой переменной:

for (i in 1:nrow(df)) {
  df$count[i] <- sum(df$cik == df$cik[i] &
                      df$accession == df$accession[i] &
                      df$logdate - df$filedate[i] >= 0 &
                      df$logdate - df$filedate[i] <= 30, na.rm = TRUE) 

Этот код должен выполняться на нескольких миллионах строк, но работает очень медленно.

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

Ответы [ 2 ]

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

Мы могли бы использовать between

library(dplyr)
df %>% 
    mutate(count = as.integer((between(as.numeric(logdate - filedate),
              0, 30)) & !is.na(filedate)))

Или, если это необходимо сделать group_by

df %>% 
       mutate(count = (between(as.numeric(logdate - filedate),
           0, 30)) & !is.na(filedate)) %>%
       group_by(cik, accession) %>% 
       mutate(count = sum(count)* count)

data

df <- structure(list(cik = c(3L, 3L, 3L, 3L, 9L, 13L, 14L, 14L, 14L, 
18L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L), accession = c("0000000003-15-000335", 
"0000000003-96-000001", "0000350001-16-206023", "0000934850-98-001281", 
"0001047469-15-006597", "0001156175-14-000006", "0000950103-94-003177", 
"0000950103-94-003177", "0000950112-94-000770", "0000774467-94-000134", 
"0000080255-05-000285", "0000893220-03-000038", "0000893220-04-000596", 
"0000893220-05-000728", "0000893220-06-000686", "0000893220-06-001733", 
"0000893220-06-002144", "0000893220-06-002635", "0000893220-07-000678", 
"0000893220-07-000678"), logdate = structure(c(16850, 12780, 
16904, 12780, 16653, 16127, 16435, 16769, 17135, 17135, 13255, 
17071, 12695, 13255, 16531, 13367, 13844, 13844, 13837, 17122
), class = "Date"), filedate = structure(c(NA, 9540, NA, 10287, 
16652, NA, 8946, 8946, 8848, 8818, 12825, 12067, 12509, 12873, 
13235, 13367, 13426, 13497, 13581, 13581), class = "Date")), row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15", "16", "17", "18", "19", "20"), class = "data.frame")
0 голосов
/ 17 января 2020

Разницу во времени между logdate и filedate можно найти с помощью пакетов lubridate, затем отфильтровать по продолжительности менее 30 дней и сгруппировать по времени cik, accession и diff для подсчета.

В конце вы получите количество уникальных комбинаций cik, accession и diff time.

library(tidyverse)
library(lubridate)
df %>% mutate(diff = ymd(logdate)-ymd(filedate)) %>% 
  filter(diff <= 30) %>% 
  group_by(cik, accession, diff) %>%
  count()

# A tibble: 2 x 4
# Groups:   cik, accession, diff [2]
    cik accession            diff       n
  <int> <chr>                <drtn> <int>
1     9 0001047469-15-006597 1 days     1
2    20 0000893220-06-001733 0 days     1

Это то, что вы ищете?

Данные

structure(list(cik = c(3L, 3L, 3L, 3L, 9L, 13L, 14L, 14L, 14L, 
18L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L), accession = c("0000000003-15-000335", 
"0000000003-96-000001", "0000350001-16-206023", "0000934850-98-001281", 
"0001047469-15-006597", "0001156175-14-000006", "0000950103-94-003177", 
"0000950103-94-003177", "0000950112-94-000770", "0000774467-94-000134", 
"0000080255-05-000285", "0000893220-03-000038", "0000893220-04-000596", 
"0000893220-05-000728", "0000893220-06-000686", "0000893220-06-001733", 
"0000893220-06-002144", "0000893220-06-002635", "0000893220-07-000678", 
"0000893220-07-000678"), logdate = c("2016-02-19", "2004-12-28", 
"2016-04-13", "2004-12-28", "2015-08-06", "2014-02-26", "2014-12-31", 
"2015-11-30", "2016-11-30", "2016-11-30", "2006-04-17", "2016-09-27", 
"2004-10-04", "2006-04-17", "2015-04-06", "2006-08-07", "2007-11-27", 
"2007-11-27", "2007-11-20", "2016-11-17"), filedate = c(NA, "1996-02-14", 
NA, "1998-03-02", "2015-08-05", NA, "1994-06-30", "1994-06-30", 
"1994-03-24", "1994-02-22", "2005-02-11", "2003-01-15", "2004-04-01", 
"2005-03-31", "2006-03-28", "2006-08-07", "2006-10-05", "2006-12-15", 
"2007-03-09", "2007-03-09")), row.names = c(NA, -20L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x55e759e0c680>)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...