我会通过的文件data.table
,也从一些对话在这里的发现上,这样rbindlist
应该是优于rbind
。
我想知道为什么是rbindlist
优于rbind
以及其中场景rbindlist
的确有过人之处超过rbind
?
是否有内存利用率方面的任何优势?
我会通过的文件data.table
,也从一些对话在这里的发现上,这样rbindlist
应该是优于rbind
。
我想知道为什么是rbindlist
优于rbind
以及其中场景rbindlist
的确有过人之处超过rbind
?
是否有内存利用率方面的任何优势?
rbindlist
是的优化版本do.call(rbind, list(...))
其被用于使用时正在缓慢已知rbind.data.frame
这表明其中有些问题rbindlist
闪耀的
按行data.frames列表的快速矢量合并
麻烦转换使用do.call和ldply data.frames(〜1元)单data.frame的一长串
这些具有基准,显示它的速度有多快可以。
rbind.data.frame
做大量检查,并且将名称相匹配。 (即rbind.data.frame将占事实,列可以以不同的顺序,并通过名称匹配), rbindlist
不会做这样的检查,而将位置加入
例如
do.call(rbind, list(data.frame(a = 1:2, b = 2:3), data.frame(b = 1:2, a = 2:3)))
## a b
## 1 1 2
## 2 2 3
## 3 2 1
## 4 3 2
rbindlist(list(data.frame(a = 1:5, b = 2:6), data.frame(b = 1:5, a = 2:6)))
## a b
## 1: 1 2
## 2: 2 3
## 3: 1 2
## 4: 2 3
它曾经很难对付factors
,因为这已经被修正了一个错误:
rbindlist 2个data.tables其中之一具有因数等具有字符类型为列 ( 错误#2650 )
它带有重复列名的问题
看到警告信息:在rbindlist(allargs):来港受到胁迫介绍:可能的错误在data.table? ( 错误#2384 )
rbindlist
可以处理lists
data.frames
和data.tables
,并且将返回而不rownames一个data.table
您可以使用rownames的混乱得到do.call(rbind, list(...))
见
如何使用rbind内do.call时避免行的重命名?
在存储器方面rbindlist
在实施C
,所以是高效的存储器,它使用setattr
设置由参考属性
rbind.data.frame
在实施R
,它做大量分配的,并且使用attr<-
和class<-
和rownames<-
所有这些都将(内部)创建创建data.frame的副本。
通过v1.9.2
, rbindlist
已经发展的非常迅速,实现许多功能,包括:
- 选择最高
SEXPTYPE
列,同时结合-在实施v1.9.2
收盘FR#2456和错误#4981 。- 处理
factor
正确列-在第一次实施v1.8.10
收盘错误#2650 ,并延伸至结合精心有序的因素v1.9.2
同时,关闭FR#4856和错误#5019 。
此外,在v1.9.2
, rbind.data.table
也获得了fill
的说法,它允许通过填充缺少的列进行绑定,在R.实施
现在,在v1.9.3
,则对这些现有的功能更加改进:
rbindlist
获得一个参数use.names
,默认是FALSE
的向后兼容性。rbindlist
也获得一个参数fill
,默认情况下也是FALSE
为了向后兼容。- 这些功能在C中的所有执行,并认真撰写同时加入的功能在速度上不妥协。
- 由于
rbindlist
现在可以通过名称相匹配,并填写缺少的列,rbind.data.table
只是调用rbindlist
现在。 唯一的区别是,use.names=TRUE
默认为rbind.data.table
,为了向后兼容。
rbind.data.frame
减慢颇有几分主要是由于可避免(通过移动到C)是复印件(@mnel指出为好)。 我认为这不是唯一的原因。 检查/匹配列名的实现rbind.data.frame
也能拿当每个data.frame很多列慢,有很多这样的data.frames绑定(如下图所示基准)。
然而, rbindlist
缺乏(ED)的某些功能(如检查因子水平或匹配名称)承担朝它比快很小(或没有)重量rbind.data.frame
。 这是因为他们是用C认真贯彻落实,对速度和内存优化。
下面是突出了有效的结合,同时也在使用列名匹配的基准rbindlist
的use.names
从功能v1.9.3
。 所述数据集包含的每个大小为10 * 500 10000个data.frames。
注意:这个测试已经更新到包括比较dplyr
的bind_rows
library(data.table) # 1.11.5, 2018-06-02 00:09:06 UTC
library(dplyr) # 0.7.5.9000, 2018-06-12 01:41:40 UTC
set.seed(1L)
names = paste0("V", 1:500)
cols = 500L
foo <- function() {
data = as.data.frame(setDT(lapply(1:cols, function(x) sample(10))))
setnames(data, sample(names))
}
n = 10e3L
ll = vector("list", n)
for (i in 1:n) {
.Call("Csetlistelt", ll, i, foo())
}
system.time(ans1 <- rbindlist(ll))
# user system elapsed
# 1.226 0.070 1.296
system.time(ans2 <- rbindlist(ll, use.names=TRUE))
# user system elapsed
# 2.635 0.129 2.772
system.time(ans3 <- do.call("rbind", ll))
# user system elapsed
# 36.932 1.628 38.594
system.time(ans4 <- bind_rows(ll))
# user system elapsed
# 48.754 0.384 49.224
identical(ans2, setDT(ans3))
# [1] TRUE
identical(ans2, setDT(ans4))
# [1] TRUE
绑定,这样的列,但不检查名称只花了1.3,其中作为检查的列名,并结合适当拿了仅需1.5秒以上。 相比于基础的解决方案,这是快14倍,18倍和速度比dplyr
的版本。