我通常使用排序很好的大型数据框(或者可以轻松排序)。
给定两个数据帧,两者都按'用户'排序
some.data <user> <data_1> <data_2>
user <user> <user_attr_1> <user_attr_2>
我运行m = merge(some.data,user)
,收到结果为:
m = <user> <data_1> <data_2> <user_attr_1> <user_attr_2>
这很好。
但是merge
没有利用这些数据帧在公共列上排序,使得合并相当漂亮的CPU /内存很重。但是,这种合并可以在O(n)
我想知道R中是否有办法对排序数据集进行有效合并?
答案 0 :(得分:5)
我对此没有任何经验,但据我所知,这是data.table
包旨在改进的问题之一。
出于大多数实际目的,data.table
= data.frame
+ index
。因此,当正确使用时,这可以提高相当多的大型操作的性能。
将data.frame
转换为data.table
(即添加索引)可能需要一些时间(尽管我希望这会得到很好的优化),但是一旦你得到了它up,像merge这样的函数可以很容易地使用索引来获得更好的性能。
答案 1 :(得分:0)
如果您的公共密钥/索引集完全重叠,那就是......
Reduce(`&`, user$user.id %in% some.data$user.id)
...返回TRUE,如你所说,它们是排序的,并且没有密钥重复,那么你的合并问题就会减少到向data.frame添加列。沿着......的路线......
library(log4r)
t1 <- system.time(z <- merge(user, some.data, by='user.id'))
info(my.logger, paste('Elapsed time with merge():', t1['elapsed']))
t2 <- Sys.time()
r <- data.frame(user.id=user$user.id, V1.x=user$V1, V2.x=user$V2)
r[,names(some.data)] <- some.data[,names(some.data)
t3 <- Sys.time()
info(my.logger, paste('Elapsed time without:', t3-t2))
如果上面的假设不成立,那么关键集,翻译函数,NA填充的集合会稍微混乱,但单独的合并和重叠假设会让你前进很长时间。
另请注意,秒接近的时间是有偏差的,因为它调用两次Sys.time(),而不像merge()调用system.time()而只调用一次。 (请原谅我对S.O.加价的蹩脚使用)