Другой метод - менее-частый, но может быть полезен время от времени (в зависимости от того, как / где вы его применяете).Функция outer
эффективно дает вам все комбинации двух векторов (аналогично, но отличается от expand.grid
).
outer(seq_len(nrow(df1)), seq_len(nrow(df2)),
function(i, j) df2$x[j] >= df1$a[i] & df2$x[j] < df1$b[i])
# [,1] [,2] [,3] [,4] [,5]
# [1,] FALSE TRUE TRUE TRUE FALSE
# [2,] TRUE TRUE FALSE TRUE TRUE
# [3,] FALSE FALSE FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE FALSE FALSE
# [5,] FALSE FALSE FALSE FALSE FALSE
# [6,] TRUE TRUE FALSE TRUE TRUE
# [7,] FALSE FALSE FALSE FALSE FALSE
# [8,] FALSE FALSE FALSE FALSE FALSE
На самом деле есть только один вызов функции, где, если вы должны смотреть, когдаэто называется, вы увидите это:
i
# [1] 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4
# [37] 5 6 7 8
j
# [1] 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 5 5 5 5
# [37] 5 5 5 5
Отсюда эта внутренняя функция разворачивается в нечто вроде:
# df2$x[j] >= df1$a[i] & df2$x[j] < df1$b[i] # i,j
df2$x[1] >= df1$a[1] & df2$x[1] < df1$b[1] # 1,1
df2$x[1] >= df1$a[2] & df2$x[1] < df1$b[2] # 2,1
df2$x[1] >= df1$a[3] & df2$x[1] < df1$b[3] # 3,1
# ...
df2$x[1] >= df1$a[8] & df2$x[1] < df1$b[8] # 8,1
df2$x[2] >= df1$a[1] & df2$x[2] < df1$b[1] # 1,2
df2$x[2] >= df1$a[2] & df2$x[2] < df1$b[2] # 2,2
# ...
df2$x[5] >= df1$a[7] & df2$x[5] < df1$b[7] # 7,5
df2$x[5] >= df1$a[8] & df2$x[5] < df1$b[8] # 8,5
, а затем принимает форму matrix
с соответствующимиколичество строк и столбцов в зависимости от длины входных векторов.(С этой функцией outer
-произведения вы можете сделать множество вещей, похожих на матрицы, это переходит от математического к поиску / вычислению.)
Теперь, когда у вас есть matrix
из logical
s, достаточно просто определить суммы строк с помощью colSums
:
rowSums(outer(seq_len(nrow(df1)), seq_len(nrow(df2)),
function(i, j) df2$x[j] >= df1$a[i] & df2$x[j] < df1$b[i]))
# [1] 3 4 0 0 0 4 0 0
(которые могли быть назначены с помощью df1$counter4 <- rowSums(...)
)