合并两个没有共同列的数据表

huangapple go评论92阅读模式
英文:

Merging two data.tables that don't have common columns

问题

我想合并两个没有共同列的data.table,最终结果将有N1*N2行,其中N1N2分别是每个数据框中的行数。

使用基本的R可以完成这个操作:

  1. A <- data.frame(id = 1:6, value = 19:24)
  2. B <- data.frame(value2 = c(25, 25, 26, 26), value3 = 4:5)
  3. A
  4. #> id value
  5. #> 1 1 19
  6. #> 2 2 20
  7. #> 3 3 21
  8. #> 4 4 22
  9. #> 5 5 23
  10. #> 6 6 24
  11. B
  12. #> value2 value3
  13. #> 1 25 4
  14. #> 2 25 5
  15. #> 3 26 4
  16. #> 4 26 5
  17. merge(A, B, all = TRUE)
  18. #> id value value2 value3
  19. #> 1 1 19 25 4
  20. #> 2 2 20 25 4
  21. #> 3 3 21 25 4
  22. #> 4 4 22 25 4
  23. #> 5 5 23 25 4
  24. #> 6 6 24 25 4
  25. #> 7 1 19 25 5
  26. #> 8 2 20 25 5
  27. #> 9 3 21 25 5
  28. #> 10 4 22 25 5
  29. #> 11 5 23 25 5
  30. #> 12 6 24 25 5
  31. #> 13 1 19 26 4
  32. #> 14 2 20 26 4
  33. #> 15 3 21 26 4
  34. #> 16 4 22 26 4
  35. #> 17 5 23 26 4
  36. #> 18 6 24 26 4
  37. #> 19 1 19 26 5
  38. #> 20 2 20 26 5
  39. #> 21 3 21 26 5
  40. #> 22 4 22 26 5
  41. #> 23 5 23 26 5
  42. #> 24 6 24 26 5

但是,如果现在有两个data.table而不是dataframes,会出现错误:

  1. library(data.table)
  2. A <- data.table(id = 1:6, value = 19:24)
  3. B <- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)
  4. merge(A, B, all = TRUE)
  5. #> Error in merge.data.table(A, B, all = TRUE): A non-empty vector of column names for `by` is required.

如何使用data.table来重现基本R的行为(不一定要使用merge())?

英文:

I want to merge two data.tables that don't have a common column, so I would end up with N1*N2 rows, where N1 and N2 are the number of rows in each dataframe.

Doing this with base R works:

  1. A &lt;- data.frame(id = 1:6, value = 19:24)
  2. B &lt;- data.frame(value2 = c(25, 25, 26, 26), value3 = 4:5)
  3. A
  4. #&gt; id value
  5. #&gt; 1 1 19
  6. #&gt; 2 2 20
  7. #&gt; 3 3 21
  8. #&gt; 4 4 22
  9. #&gt; 5 5 23
  10. #&gt; 6 6 24
  11. B
  12. #&gt; value2 value3
  13. #&gt; 1 25 4
  14. #&gt; 2 25 5
  15. #&gt; 3 26 4
  16. #&gt; 4 26 5
  17. merge(A, B, all = TRUE)
  18. #&gt; id value value2 value3
  19. #&gt; 1 1 19 25 4
  20. #&gt; 2 2 20 25 4
  21. #&gt; 3 3 21 25 4
  22. #&gt; 4 4 22 25 4
  23. #&gt; 5 5 23 25 4
  24. #&gt; 6 6 24 25 4
  25. #&gt; 7 1 19 25 5
  26. #&gt; 8 2 20 25 5
  27. #&gt; 9 3 21 25 5
  28. #&gt; 10 4 22 25 5
  29. #&gt; 11 5 23 25 5
  30. #&gt; 12 6 24 25 5
  31. #&gt; 13 1 19 26 4
  32. #&gt; 14 2 20 26 4
  33. #&gt; 15 3 21 26 4
  34. #&gt; 16 4 22 26 4
  35. #&gt; 17 5 23 26 4
  36. #&gt; 18 6 24 26 4
  37. #&gt; 19 1 19 26 5
  38. #&gt; 20 2 20 26 5
  39. #&gt; 21 3 21 26 5
  40. #&gt; 22 4 22 26 5
  41. #&gt; 23 5 23 26 5
  42. #&gt; 24 6 24 26 5

But if I now have two data.tables and not dataframes anymore, it errors:

  1. library(data.table)
  2. A &lt;- data.table(id = 1:6, value = 19:24)
  3. B &lt;- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)
  4. merge(A, B, all = TRUE)
  5. #&gt; Error in merge.data.table(A, B, all = TRUE): A non-empty vector of column names for `by` is required.

How can I reproduce the base R behavior with data.table (without necessarily using merge())?

答案1

得分: 5

data.table中,你正在寻找一个交叉连接。有一个CJ函数,但它只能用于一个数据集,否则你可以这样做:

  1. res <- setkey(A[, c(k=1, .SD)], k)[B[, c(k=1, .SD)], allow.cartesian = TRUE][, k := NULL]
  2. res
  3. id value value2 value3
  4. 1: 1 19 25 4
  5. 2: 2 20 25 4
  6. 3: 3 21 25 4
  7. 4: 4 22 25 4
  8. 5: 5 23 25 4
  9. 6: 6 24 25 4
  10. 7: 1 19 25 5
  11. 8: 2 20 25 5
  12. 9: 3 21 25 5
  13. 10: 4 22 25 5
  14. 11: 5 23 25 5
  15. 12: 6 24 25 5
  16. 13: 1 19 26 4
  17. 14: 2 20 26 4
  18. 15: 3 21 26 4
  19. 16: 4 22 26 4
  20. 17: 5 23 26 4
  21. 18: 6 24 26 4
  22. 19: 1 19 26 5
  23. 20: 2 20 26 5
  24. 21: 3 21 26 5
  25. 22: 4 22 26 5
  26. 23: 5 23 26 5
  27. 24: 6 24 26 5
  28. id value value2 value3

注意备用的dplyr解决方案:

  1. dplyr::cross_join(A, B)
英文:

You are looking for a cross-join. In data.table, there is a CJ function but it only works with one data set, otherwise you can do:

  1. res &lt;- setkey(A[, c(k=1, .SD)], k)[B[, c(k=1, .SD)], allow.cartesian = TRUE][, k := NULL]
  2. res
  3. id value value2 value3
  4. 1: 1 19 25 4
  5. 2: 2 20 25 4
  6. 3: 3 21 25 4
  7. 4: 4 22 25 4
  8. 5: 5 23 25 4
  9. 6: 6 24 25 4
  10. 7: 1 19 25 5
  11. 8: 2 20 25 5
  12. 9: 3 21 25 5
  13. 10: 4 22 25 5
  14. 11: 5 23 25 5
  15. 12: 6 24 25 5
  16. 13: 1 19 26 4
  17. 14: 2 20 26 4
  18. 15: 3 21 26 4
  19. 16: 4 22 26 4
  20. 17: 5 23 26 4
  21. 18: 6 24 26 4
  22. 19: 1 19 26 5
  23. 20: 2 20 26 5
  24. 21: 3 21 26 5
  25. 22: 4 22 26 5
  26. 23: 5 23 26 5
  27. 24: 6 24 26 5
  28. id value value2 value3

Note the alternative dplyr solution:

  1. dplyr::cross_join(A, B)

答案2

得分: 1

来自data.table的替代方案:

  1. library(data.table)
  2. A <- data.table(id = 1:6, value = 19:24)
  3. B <- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)
  4. CJDT <- function(...) {
  5. Reduce(function(DT1, DT2) cbind(DT1, DT2[rep(1:.N, each=nrow(DT1))]), list(...))
  6. }
  7. CJDT(A, B)
  8. #> id value value2 value3
  9. #> 1: 1 19 25 4
  10. #> 2: 2 20 25 4
  11. #> 3: 3 21 25 4
  12. #> 4: 4 22 25 4
  13. #> 5: 5 23 25 4
  14. #> 6: 6 24 25 4
  15. #> 7: 1 19 25 5
  16. #> 8: 2 20 25 5
  17. #> 9: 3 21 25 5
  18. #> 10: 4 22 25 5
  19. #> 11: 5 23 25 5
  20. #> 12: 6 24 25 5
  21. #> 13: 1 19 26 4
  22. #> 14: 2 20 26 4
  23. #> 15: 3 21 26 4
  24. #> 16: 4 22 26 4
  25. #> 17: 5 23 26 4
  26. #> 18: 6 24 26 4
  27. #> 19: 1 19 26 5
  28. #> 20: 2 20 26 5
  29. #> 21: 3 21 26 5
  30. #> 22: 4 22 26 5
  31. #> 23: 5 23 26 5
  32. #> 24: 6 24 26 5
  33. #> id value value2 value3

创建于2023-02-06,使用reprex v2.0.2

英文:

An alternative coming from this GitHub issue on the data.table repo:

  1. library(data.table)
  2. A &lt;- data.table(id = 1:6, value = 19:24)
  3. B &lt;- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)
  4. CJDT &lt;- function(...) {
  5. Reduce(function(DT1, DT2) cbind(DT1, DT2[rep(1:.N, each=nrow(DT1))]), list(...))
  6. }
  7. CJDT(A, B)
  8. #&gt; id value value2 value3
  9. #&gt; 1: 1 19 25 4
  10. #&gt; 2: 2 20 25 4
  11. #&gt; 3: 3 21 25 4
  12. #&gt; 4: 4 22 25 4
  13. #&gt; 5: 5 23 25 4
  14. #&gt; 6: 6 24 25 4
  15. #&gt; 7: 1 19 25 5
  16. #&gt; 8: 2 20 25 5
  17. #&gt; 9: 3 21 25 5
  18. #&gt; 10: 4 22 25 5
  19. #&gt; 11: 5 23 25 5
  20. #&gt; 12: 6 24 25 5
  21. #&gt; 13: 1 19 26 4
  22. #&gt; 14: 2 20 26 4
  23. #&gt; 15: 3 21 26 4
  24. #&gt; 16: 4 22 26 4
  25. #&gt; 17: 5 23 26 4
  26. #&gt; 18: 6 24 26 4
  27. #&gt; 19: 1 19 26 5
  28. #&gt; 20: 2 20 26 5
  29. #&gt; 21: 3 21 26 5
  30. #&gt; 22: 4 22 26 5
  31. #&gt; 23: 5 23 26 5
  32. #&gt; 24: 6 24 26 5
  33. #&gt; id value value2 value3

<sup>Created on 2023-02-06 with reprex v2.0.2</sup>

答案3

得分: 0

  1. A[, as.list(B), names(A)]

结果

  1. id value value2 value3
  2. 1: 1 19 25 4
  3. 2: 1 19 25 5
  4. 3: 1 19 26 4
  5. 4: 1 19 26 5
  6. 5: 2 20 25 4
  7. 6: 2 20 25 5
  8. 7: 2 20 26 4
  9. 8: 2 20 26 5
  10. 9: 3 21 25 4
  11. 10: 3 21 25 5
  12. 11: 3 21 26 4
  13. 12: 3 21 26 5
  14. 13: 4 22 25 4
  15. 14: 4 22 25 5
  16. 15: 4 22 26 4
  17. 16: 4 22 26 5
  18. 17: 5 23 25 4
  19. 18: 5 23 25 5
  20. 19: 5 23 26 4
  21. 20: 5 23 26 5
  22. 21: 6 24 25 4
  23. 22: 6 24 25 5
  24. 23: 6 24 26 4
  25. 24: 6 24 26 5

数据

  1. A <- data.table(id = 1:6, value = 19:24)
  2. B <- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)
  1. <details>
  2. <summary>英文:</summary>
  3. A[, as.list(B), names(A)]
  4. **results**
  5. id value value2 value3
  6. 1: 1 19 25 4
  7. 2: 1 19 25 5
  8. 3: 1 19 26 4
  9. 4: 1 19 26 5
  10. 5: 2 20 25 4
  11. 6: 2 20 25 5
  12. 7: 2 20 26 4
  13. 8: 2 20 26 5
  14. 9: 3 21 25 4
  15. 10: 3 21 25 5
  16. 11: 3 21 26 4
  17. 12: 3 21 26 5
  18. 13: 4 22 25 4
  19. 14: 4 22 25 5
  20. 15: 4 22 26 4
  21. 16: 4 22 26 5
  22. 17: 5 23 25 4
  23. 18: 5 23 25 5
  24. 19: 5 23 26 4
  25. 20: 5 23 26 5
  26. 21: 6 24 25 4
  27. 22: 6 24 25 5
  28. 23: 6 24 26 4
  29. 24: 6 24 26 5
  30. **data**
  31. A &lt;- data.table(id = 1:6, value = 19:24)
  32. B &lt;- data.table(value2 = c(25, 25, 26, 26), value3 = 4:5)
  33. </details>

huangapple
  • 本文由 发表于 2023年2月6日 21:05:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75361701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定