【问题标题】:Using roll=TRUE with allow.cartesian=TRUE使用 roll=TRUE 和 allow.cartesian=TRUE
【发布时间】:2014-05-16 19:16:59
【问题描述】:

进行笛卡尔连接和使用前滚功能的最佳方法是什么,但将滚动功能应用于连接表中的每个替代系列,而不是整个系列。

最好用一个例子来解释:

library(data.table)
A = data.table(x = c(1,2,3,4,5), y = letters[1:5])
B = data.table(x = c(1,2,3,1,4), f = c("Alice","Alice","Alice", "Bob","Bob"), z = 101:105)
setkey(B,x)
C = B[A, roll = TRUE, allow.cartesian=TRUE, rollends = FALSE]

A
B
C[f == "Alice"]
C[f == "Bob"]
C

所以我们有两个起始表:

> A
   x y
1: 1 a
2: 2 b
3: 3 c
4: 4 d
5: 5 e
> B
   x     f   z
1: 1 Alice 101
2: 1   Bob 104
3: 2 Alice 102
4: 3 Alice 103
5: 4   Bob 105

我想加入这些,以便我有 每个 A 中的 x 值我同时拥有 AliceBob 行,如果其中一个缺失(但不会滚动到最后)。这并不像我目前得到的那样工作:

> C[f == "Alice"]
   x     f   z y
1: 1 Alice 101 a
2: 2 Alice 102 b
3: 3 Alice 103 c
> C[f == "Bob"]
   x   f   z y
1: 1 Bob 104 a
2: 4 Bob 105 d
> C
   x     f   z y
1: 1 Alice 101 a
2: 1   Bob 104 a
3: 2 Alice 102 b
4: 3 Alice 103 c
5: 4   Bob 105 d
6: 5    NA  NA e

因为 Alice 存在 2 和 3,所以它不会向前滚动 Bob 的数据。我需要 Bob 的额外行,所以我想得到:

> C[f == "Alice"]
   x     f   z y
1: 1 Alice 101 a
2: 2 Alice 102 b
3: 3 Alice 103 c
> C[f == "Bob"]
   x   f   z y
1: 1 Bob 104 a
2: 2 Bob 104 b  # THESE ROWS ARE MISSING
3: 3 Bob 104 c  # THESE ROWS ARE MISSING
4: 4 Bob 105 d
> C
   x     f   z y
1: 1 Alice 101 a
2: 1   Bob 104 a
3: 2 Alice 102 b
4: 2   Bob 104 b  # THESE ROWS ARE MISSING
5: 3 Alice 103 c
6: 3   Bob 104 c  # THESE ROWS ARE MISSING
7: 4   Bob 105 d
8: 5    NA  NA e

【问题讨论】:

    标签: r join data.table cartesian-product


    【解决方案1】:

    我还找到了另一种方法。我已经接受了另一个答案,因为它产生的结果更接近问题所要求的结果,但这对某些人也可能有用。不同之处在于系列结束时会发生什么。

    C = B[, .SD[A, roll = TRUE, rollends = FALSE], by = f]
    setkey(C, x)
    
    > C
            f x   z y
     1: Alice 1 101 a
     2:   Bob 1 104 a
     3: Alice 2 102 b
     4:   Bob 2 104 b
     5: Alice 3 103 c
     6:   Bob 3 104 c
     7: Alice 4  NA d
     8:   Bob 4 105 d
     9: Alice 5  NA e
    10:   Bob 5  NA e
    

    第 9 行和第 10 行是唯一的区别;在 eddi 的回答中,这些被组合为一行,两列中都有 NA

    当我在更大的 data.tables 上进行测试时,这个解决方案也比 eddi 的稍慢(尽管两者都非常快)。

    【讨论】:

      【解决方案2】:

      给你:

      setkey(B, f, x)
      
      setkey(B[CJ(unique(f), unique(x)), allow.cartesian = T,
               roll = T, rollends = c(F,F)], x)[A, allow.cartesian = T]
      #   x     f   z y
      #1: 1 Alice 101 a
      #2: 1   Bob 104 a
      #3: 2 Alice 102 b
      #4: 2   Bob 104 b
      #5: 3 Alice 103 c
      #6: 3   Bob 104 c
      #7: 4 Alice  NA d
      #8: 4   Bob 105 d
      #9: 5    NA  NA e
      

      您可以过滤掉NA 以满足您的需求。

      【讨论】:

      • 感谢@eddi,我接受了这个答案,因为它是最快且准确地回答问题的,但我还在下面发布了一个我偶然发现的替代方案,因为它看起来足够不同并且可能对某人有用。
      • 读到这里让我觉得最好有办法在 [] 内设置键以保持自然的左右数据流
      • @ClaytonStanley 这样的选项(key 的参数[.data.table)曾短暂可用(我认为是在 1.8.11 中),但它被回滚了,因为它看起来不像用了很多,有点混乱
      • @eddi 我知道这超出了帖子的讨论范围,但是如何获得类似:tbl[..][, setkey(.SD, x)][..] 的内容;只是一个想法。
      • @ClaytonStanley 这与dt[, list(a, b, c)]dt[, .SD] 的处理方式相同——这是一个新的data.table,而不是原始dt 的“一部分”
      猜你喜欢
      • 2020-12-10
      • 2016-03-27
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多