r - 在 R 中进行子集化的最快方法

标签 r

我有一个名为 main 的数据框,它有 400,000 行,我想对其进行子集化以检索 1 行或多行。

这里的一个例子是一个数据框,它显示了我正在使用 subset 函数的子集类型:

main <- data.frame(date = as.POSIXct(c("2015-01-01 07:44:00 GMT","2015-02-02 09:46:00 GMT")),
                   name= c("bob","george"),
                   value=c(1,522), 
                   id= c(5,2))

subset(main, date == "2015-01-01 07:44:00" & name == "bob" & value == 1)

这行得通,但速度很慢,我认为这是因为我正在处理 400k 行的数据框。有什么想法可以使子集化更快吗?

最佳答案

我建议使用键控 data.table。以下是设置方法(修改示例):

require(data.table)
mainDT <- data.table(main)
setkey(mainDT,V1,V2,V3)

我们现在可以使用如下语法基于相等条件进行子集

mainDT[J("a","A")]

mainDT[J(c("a","b"),"A",1)]

which subsets to where V1 %in% c("a","b") (相当于 V1=="a"|V1=="b").


这是一个速度比较:

require(rbenchmark)
benchmark(
  "["       = main[main$V1=="a" & main$V2=="A",],
  "subset"  = subset(main,V1=="a" & V2=="A"),
  "DT[J()]" = mainDT[J("a","A")],
  replications=5
)[,1:6]

在我的电脑上给出了这些结果:

     test replications elapsed relative user.self sys.self
1       [            5    5.96       NA      5.38     0.57
3 DT[J()]            5    0.00       NA      0.00     0.00
2  subset            5    6.93       NA      6.20     0.72

因此,使用 J 进行子集化是即时的,而其他两种方法需要几秒钟。但是,以这种方式使用 J 进行子集化是有限的:

  • 仅用于平等条件。
  • 对于上面的简单语法,您需要按照键的顺序传递参数。但是,您可以使用 mainDT[J("a",unique(V2),2)] 选择 V1=="a"& V3 == 2 的位置,它是还是挺快的。

你可以用 data.frame 做的一切也可以用 data.table 完成。例如,subset(mainDT,V1=="a"& V2=="A") 仍然有效。因此,通常将 data.frames 切换为 data.tables 不会有任何损失。您可以使用 setDT(main) 就地转换为 data.table。


示例代码如下:

n  = 1e7
n3 = 1e3

set.seed(1)
main <- data.frame(
  V1=sample(letters,n,replace=TRUE),
  V2=sample(c(letters,LETTERS),n,replace=TRUE),
  V3=sample(1:n3,n,replace=TRUE),
  V4=rnorm(n))

在上述基准测试中看到的改进会因您的数据而异。当您有很多观察值 (n) 或键的唯一值很少(例如 n3)时,使用键控数据表进行子集化的好处应该更大。

关于r - 在 R 中进行子集化的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29975596/

相关文章:

r - 无法预测R中的线性模型

r - 将函数应用于参数网格并返回 purrr 中的列表列表

r - 为什么基R中的Date类有一个double支持

r - R中它们之间的每一列的总和

r - 如何用非事件的开始时间和结束时间填充每 2 行

R:迭代添加新列

r - 如何在 R 中安装软件包 keras

将 hdf 文件读入 R 并将它们转换为 geoTIFF 栅格

r - R 中 "!is.null()"的替代方案

r - 使用 facet_wrap 和两个变量在 R 中排序条形图