R 选择具有特定ID值的数据帧行的最快方法是什么?

R 选择具有特定ID值的数据帧行的最快方法是什么?,r,optimization,dataframe,R,Optimization,Dataframe,现在我正在用计算机分析一些数据 row = dataset[dataset$id == id1,] 及 其中所有id值都是整数 然而,在使用较大的数据集时,我得到了令人失望的缓慢结果。有什么方法可以加快这个特定任务的速度吗?使用data.table,我们可以在列上设置键,按递增顺序指定的列对数据进行物理重新排序,这样我们就可以使用二进制搜索对数据进行子集 library(data.table) setkey(setDT(data1), id)[.(id1)] 或者,从data.table版本

现在我正在用计算机分析一些数据

row = dataset[dataset$id == id1,]

其中所有id值都是整数

然而,在使用较大的数据集时,我得到了令人失望的缓慢结果。有什么方法可以加快这个特定任务的速度吗?

使用data.table,我们可以在列上设置键,按递增顺序指定的列对数据进行物理重新排序,这样我们就可以使用二进制搜索对数据进行子集

library(data.table)
setkey(setDT(data1), id)[.(id1)]
或者,从data.table版本1.9.4+,DT[x=.]和DT[x%in%.]形式的子集都在内部进行了优化,以自动创建索引,然后在连续运行时使用二进制搜索对子集进行搜索,速度非常快,请参见下面的基准测试

setDT(data1)[id == id1] # internally optimised to generate index automatically
查看以获取更多信息

数据
下面是base[和dplyrfilter之间的比较:

set.seed(29)
dat2 <- data.frame(id= sample(1:6, 3e6, replace=TRUE), val=rnorm(3e6))
library(dplyr)
system.time(dplyr::filter(dat2, id==5))
 user  system elapsed 
0.029   0.004   0.033 
system.time(dat2[dat2$id==5,])
 user  system elapsed 
0.236   0.012   0.248 

请添加上下文和示例
 set.seed(24)
 data1 <- data.frame(id= sample(1:6, 25, replace=TRUE), val=rnorm(25))
 id1 <- 5L
set.seed(29)
dat2 <- data.frame(id= sample(1:100, 1e8, replace=TRUE), val=rnorm(1e8))

# data.frame subset in base R
system.time(dat2[dat2$id == id1,])
#   user  system elapsed 
#  6.287   0.646   7.081 

# base R like syntax on data.table; create index and subset using binary search
system.time(setDT(dat2)[id == id1])
#  user  system elapsed 
# 0.646   0.232   0.889 
# successive runs are incredibly fast!
# 0.037   0.002   0.039
# 0.040   0.002   0.042 

# alternatively set key once 
system.time(setkey(setDT(dat2), id))
#  2.908   0.499   3.440 
# and use binary search explicitly
system.time(dat2[.(id1)])
#   user  system elapsed 
#  0.009   0.002   0.012 
set.seed(29)
dat2 <- data.frame(id= sample(1:6, 3e6, replace=TRUE), val=rnorm(3e6))
library(dplyr)
system.time(dplyr::filter(dat2, id==5))
 user  system elapsed 
0.029   0.004   0.033 
system.time(dat2[dat2$id==5,])
 user  system elapsed 
0.236   0.012   0.248