计算比当前数字低一个常量的数字
Count numbers that are lower by constant from current number
假设我有一个数字列表(即数据中的数字列。table/data.frame)。
1
5
5
10
11
12
对于列表中的每个数字,A 想要计算有多少个唯一数字比该特定数字 + 5 低。
大写的解释,第一个数=1,搜索范围是1+5=6,所以三个数都在范围内,小于等于:c(1,5,5)
,然后count unique是2 .
这一切都假设我们有附加条件,即数字不仅必须小于 current_number + 5,而且它在列表中的索引必须 >= current_number 的索引。
这种情况下的结果是:
2
2
2
3
2
1
注:有没有针对大数据集的快速解决方案,在data.frame或data.table?我的数据集相当大,有 10+M 行。
一种选择是使用 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")
sapply(yourVector + 5, function(x, y) sum(x > y), y = unique(x))
试试这个:
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
我能想到的在 base R 中最快的方法(如果 x
已排序则有效):
findInterval(x + 5, unique(x)) - cumsum(!duplicated(x)) + 1L
#[1] 2 2 2 3 2 1
编辑:排序没有问题,因为使用 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
1000 万行 2 秒。
假设我有一个数字列表(即数据中的数字列。table/data.frame)。
1
5
5
10
11
12
对于列表中的每个数字,A 想要计算有多少个唯一数字比该特定数字 + 5 低。
大写的解释,第一个数=1,搜索范围是1+5=6,所以三个数都在范围内,小于等于:c(1,5,5)
,然后count unique是2 .
这一切都假设我们有附加条件,即数字不仅必须小于 current_number + 5,而且它在列表中的索引必须 >= current_number 的索引。
这种情况下的结果是:
2
2
2
3
2
1
注:有没有针对大数据集的快速解决方案,在data.frame或data.table?我的数据集相当大,有 10+M 行。
一种选择是使用 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")
sapply(yourVector + 5, function(x, y) sum(x > y), y = unique(x))
试试这个:
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
我能想到的在 base R 中最快的方法(如果 x
已排序则有效):
findInterval(x + 5, unique(x)) - cumsum(!duplicated(x)) + 1L
#[1] 2 2 2 3 2 1
编辑:排序没有问题,因为使用 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
1000 万行 2 秒。