Подсчитайте числа, которые ниже на постоянную от текущего числа - PullRequest
6 голосов
/ 14 февраля 2020

Представьте, что у меня есть список чисел (т. Е. Столбец чисел в data.table / data.frame).

1
5
5
10
11
12

для каждого числа в списке требуется подсчитать, сколько существует уникальных чисел которые на ниже , чем это конкретное число + 5.

Объяснение в верхнем регистре, первое число = 1, диапазон поиска составляет 1 + 5 = 6, поэтому три числа находятся в диапазоне, меньше чем или равно: c(1,5,5), а затем число уникальных равно 2. Это все, если предположить, что у нас есть дополнительное условие, что число должно быть не только меньше чем current_number + 5, но и его индекс в списке должен be> = значение current_number.

Результатом в этом случае будет:

2
2
2
3
2
1

Примечание: Есть ли быстрое решение для огромного набора данных в data.frame или data.table ? Мой набор данных довольно большой, 10 + M строк.

Ответы [ 4 ]

6 голосов
/ 14 февраля 2020

Самый быстрый способ, о котором я могу думать в базе R (работает, если x отсортирован):

findInterval(x + 5, unique(x)) - cumsum(!duplicated(x)) + 1L
#[1] 2 2 2 3 2 1

edit: нет проблем с сортировкой, потому что с data.table, сортировка целых чисел тривиально:

nr <- 1e7
nn <- nr/2
set.seed(0L)
DT <- data.table(X=sample(nn, nr, TRUE))
#DT <- data.table(X=c(1,5,5,10,11,12))

system.time(
    DT[order(X), 
        COUNT := findInterval(X + 5L, unique(X)) - cumsum(!duplicated(X)) + 1L
    ]
)
#   user  system elapsed 
#   1.73    0.17    1.53 

2s для 10 миллионов строк.

5 голосов
/ 14 февраля 2020

Попробуйте это:

x <- c(1,5,5,10,11,12)

sapply(seq_along(x), function(i)
  sum(unique(x[i:length(x)]) <= (x[i] + 5)))
# [1] 2 2 2 3 2 1
2 голосов
/ 14 февраля 2020

Один из вариантов - использовать sql самосоединение

library(sqldf)


df$r <- seq(nrow(df))

sqldf('
select    a.V1
          , count(distinct b.V1) as n
from      df a
          left join df b
            on  b.V1 <= a.V1 + 5
                and b.r >= a.r
group by  a.r
')

#   V1 n
# 1  1 2
# 2  5 2
# 3  5 2
# 4 10 3
# 5 11 2
# 6 12 1

Используемые данные:

df <- structure(list(V1 = c(1L, 5L, 5L, 10L, 11L, 12L)), row.names = c(NA, 
-6L), class = "data.frame")
0 голосов
/ 14 февраля 2020
sapply(yourVector + 5, function(x, y) sum(x > y), y = unique(x))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...