我正在尝试对数据框列表执行半连接。我有大约1000个数据框,共50,000行,我想根据另一个数据框选择其中的行子集。
请考虑以下示例:
df1 <- data.frame(id = 50:150)
set.seed(1)
l <- replicate(1000,
data.frame(id = sample(1:100, 50000, replace = TRUE),
id2 = sample(letters, 50000, replace = TRUE),
info = runif(50000, 200, 300)),
simplify = FALSE)
我想根据df1
的id对l
的每个 Dataframe 进行子集化。我可以通过执行半连接或使用%in%
进行子集化来实现这一点:
library(dplyr)
semi_join(l[[1]], df1, "id")
l[[1]][l[[1]]$id %in% df1$id, ]
我正在寻找一个可以扩展到数千个 Dataframe 的快速解决方案。到目前为止,我将其 Package 在lapply
中(但可能有更快的矢量化解决方案)。
lapply(l, \(x) semi_join(x, df1, "id"))
下面是一个包含解决方案的初始基准:
bc <- bench::mark(lapply(l, \(x) semi_join(x, df1, "id")),
lapply(l, \(x) x[x$id %in% df1$id, ]), iterations = 1, check = FALSE)
> bc
# A tibble: 2 × 13
# expression min median itr/s…¹ mem_a…² gc/se…³ n_itr
# <bch:expr> <bch:tm> <bch:t> <dbl> <bch:b> <dbl> <int>
#1 lapply(l, function(x) semi_join(x, df1, "id")) 9.34s 9.34s 0.107 1.97GB 0.428 1
#2 lapply(l, function(x) x[x$id %in% df1$id, ]) 14.19s 14.19s 0.0705 2.5GB 0.282 1
1条答案
按热度按时间sczxawaw1#
更新
感谢@jblood94的评论,我们有了另一个更有效的参数,而不是使用
rep
来添加grp
列,它确实提高了性能(参见dtsplit1
)给予
如果您已经为所有“真实的的”1000个 Dataframe 修复了
50000
行,希望下面的代码可以提供一些帮助基准测试
显示