【问题标题】:R: data.table cross-join not workingR:data.table 交叉连接不起作用
【发布时间】:2014-11-11 09:06:48
【问题描述】:

我有两个想要加入的data.tables(形成笛卡尔积)。其中一个data.tables 键控在Date 向量上,另一个键控在numeric 向量上:

# data.table with dates (as numeric)
dtDates2 = data.table(date = 
                       as.numeric(seq(from = as.Date('2014/01/01'), 
                           to = as.Date('2014/07/01'), by = 'weeks')),
                     data1 = rnorm(26))

# data.table with dates
dtDates1 = data.table(date = 
                        seq(from = as.Date('2014/01/01'), 
                            to = as.Date('2014/07/01'), by = 'weeks'),
                      data1 = rnorm(26))


# data.table with customer IDs
dtCustomers = data.table(customerID = seq(1, 100),
                      data2 = rnorm(100))

setkey 并尝试使用CJ 交叉加入他们:

# cross join the two datatables
setkey(dtCustomers, customerID)
setkey(dtDates1, date)
setkey(dtDates2, date)

CJ(dtCustomers, dtDates1)
CJ(dtCustomers, dtDates2)

但得到以下错误:

Error in FUN(X[[1L]], ...) : 
  Invalid column: it has dimensions. Can't format it. If it's the result of data.table(table()), use as.data.table(table()) instead.

不知道我做错了什么。

【问题讨论】:

  • 错误信息明确告诉你不能交叉连接data.tables,只能在向量(列)上做。 ?CJ 会告诉你同样的事情。你想达到什么目的?您只是想合并这些 data.tables 吗?
  • @DavidArenburg 是的,我是。我怎样才能做到这一点?
  • 基于哪些字段?我没有看到dtCustomers 和其他两个数据集之间有任何共同的列
  • @DavidArenburg 让我更新问题以更清楚地了解我想要什么。

标签: r join data.table


【解决方案1】:

data.table 中没有开箱即用的交叉连接功能。
然而,CJ.dt 函数(类似于 CJ,但专为 data.tables 设计)可在 optiRum 包(在 CRAN 中提供)中实现笛卡尔积(交叉连接)。
你可以创建函数:

CJ.dt = function(X,Y) {
  stopifnot(is.data.table(X),is.data.table(Y))
  k = NULL
  X = X[, c(k=1, .SD)]
  setkey(X, k)
  Y = Y[, c(k=1, .SD)]
  setkey(Y, NULL)
  X[Y, allow.cartesian=TRUE][, k := NULL][]
}
CJ.dt(dtCustomers, dtDates1)
CJ.dt(dtCustomers, dtDates2)

但是有一个FR为了方便的方式来执行交叉连接填写data.table#1717,所以你可以检查那里是否有更好的交叉连接api。

【讨论】:

    【解决方案2】:

    感谢 jangorecki 提供的非常有用的功能

    我必须添加对空 X 和/或 Y 的支持:

    CJ.dt = function(X, Y) {
      stopifnot(is.data.table(X), is.data.table(Y))
    
      if(nrow(X) > 0 & nrow(Y) > 0){
        k = NULL
        X = X[, c(k = 1, .SD)]
        setkey(X, k)
        Y = Y[, c(k = 1, .SD)]
        setkey(Y, NULL)
        return(X[Y, allow.cartesian = T][, k := NULL][])
    
      } else {
        duplicatedNames <- names(Y)[names(Y) %in% names(X)]
        if(length(duplicatedNames) > 0) {
           setnames(Y, duplicatedNames, paste0("i.", duplicatedNames))
        }
        setkey(Y)
        setkey(X)
        return(cbind(X[!X], Y[!Y]))
      }
    
    }
    
    # X <- data.table(a = c(1, 2))
    # Y <- data.table(a = c(2, 3), b = c(4, 5))
    #
    # CJ.dt(X, Y)
    
    # CJ.dt(X[a > 2], Y)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-08
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 2013-05-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      相关资源
      最近更新 更多