使用R中的data.table包,我尝试使用合并方法来创建两个data.tables的carbohydrate产品,就像在基R中一样。
在基地以下工程:
#assume this order data
orders <- data.frame(date = as.POSIXct(c('2012-08-28','2012-08-29','2012-09-01')),
first.name = as.character(c('John','George','Henry')),
last.name = as.character(c('Doe','Smith','Smith')),
qty = c(10,50,6))
#and these dates
dates <- data.frame(date = seq(from = as.POSIXct('2012-08-28'),
to = as.POSIXct('2012-09-07'), by = 'day'))
#get the unique customers
cust<-unique(orders[,c('first.name','last.name')])
#using merge from base R, get the cartesian product
merge(dates, cust, by = integer(0))
然而,相同的技术在使用data.table时不起作用,并抛出以下错误:
"Error in merge.data.table(dates.dt, cust.dt, by = integer(0)) :
A non-empty vector of column names for `by` is required."
#data.table approach
library(data.table)
orders.dt <- data.table(orders)
dates.dt <- data.table(dates)
cust.dt <- unique(orders.dt[, list(first.name, last.name)])
#try to use merge (data.table) in the same manner as base
merge(dates.dt, cust.dt, by = integer(0))
Error in merge.data.table(dates.dt, cust.dt, by = integer(0)) :
A non-empty vector of column names for `by` is required.
我希望结果能反映所有日期的所有客户名称,就像在base中一样,但要以数据.表为中心。这可能吗?
4条答案
按热度按时间nfs0ujit1#
如果您首先从
cust
-嵌套框架中的第一个和最后一个构造全名,则可以使用CJ
(交叉连接)。你不能使用所有三个向量,因为会有99个项目,名字会不适当地与姓氏混合。这将返回所需的数据。table对象:
kkbh8khc2#
merge.data.table(x, y)
是一个方便的函数,它 Package 了对x[y]
的调用,因此合并需要基于两个data.table
中的列。(这就是错误消息试图告诉你的)。一种解决方法是向两个data.tables添加一个虚拟列,其唯一目的是使合并成为可能:
fhity93d3#
来自@JoshO'Brien的解决方案使用
merge
,但下面是一个类似的替代方案,它不使用(AFAIK)。如果我正确理解了
?data.table::merge
中的文档,那么X[Y]
应该比data.table::merge(X,Y)
稍快(从1.8.7版开始)。它引用了FAQ 2.12来解决这个问题,但FAQ有点令人困惑。首先,正确的参考应该是1.12,而不是2.12。它们也没有指出它们是引用merge的基本版本还是data. tableone,或者两者都引用。所以,这可能最终只是一个看起来更混乱的解决方案,它是等价的,或者它可能更快。[Edit from Matthew]谢谢:现在在v1.8.7中进行了改进(
?merge.data.table
,FAQ 1.12并添加了新的FAQ 2.24)lc8prwob4#
还有两个选择:
1.力:
base::merge(..)
1.另一个
data.table
-技巧: