【问题标题】:Generate pairwise data.frame of all combinations of two data.frame with different number of rows生成具有不同行数的两个data.frame的所有组合的成对data.frame
【发布时间】:2020-01-10 07:15:42
【问题描述】:

我必须将数据框 ab 合并到最终数据框 c

a <- data.frame(city=c("a","b","c"),detail=c(1,2,3))

b <- data.frame(city=c("x","y"),detail=c(5,6))

数据框c 应该是这样的

  city.a detail.a city.b detail.b
1      a        1      x        5
2      a        1      y        6
3      b        2      x        5
4      b        2      y        6
5      c        3      x        5
6      c        3      y        6

我想我可以使用来自tidyr 的交叉,但对于crossing(a,b) 我得到:

error: Column names `city`, `detail` must not be duplicated.
Use .name_repair to specify repair.

【问题讨论】:

    标签: r dataframe combinations tidyr


    【解决方案1】:

    是的,crossing 是正确的函数,但由于错误消息表明不应重复列名,请尝试更改列名

    names(a) <- paste0(names(a), ".a")
    names(b) <- paste0(names(b), ".b")
    tidyr::crossing(a, b)
    
    #  city.a detail.a city.b detail.b
    #  <fct>     <dbl> <fct>     <dbl>
    #1 a             1 x             5
    #2 a             1 y             6
    #3 b             2 x             5
    #4 b             2 y             6
    #5 c             3 x             5
    #6 c             3 y             6
    

    crossingexpand_grid 的包装器,因此在更正名称后,您也可以直接使用它。

    tidyr::expand_grid(a, b)
    

    【讨论】:

    • @chinsoon12 是的,这相当于data.table 中的CJ 吗?
    • 不幸的是,afaik,data.table::CJ 仍然无法进行交叉连接
    【解决方案2】:

    这是一个使用rep() + cbind() 的基本 R 解决方案,它给出了重复的列名:

    C <- `row.names<-`(cbind(a[rep(seq(nrow(a)),each = nrow(b)),],b),NULL)
    

    这样

    > C
      city detail city detail
    1    a      1    x      5
    2    a      1    y      6
    3    b      2    x      5
    4    b      2    y      6
    5    c      3    x      5
    6    c      3    y      6
    

    或者使用data.frame()获取不同列名的数据框:

    C <- data.frame(a[rep(seq(nrow(a)),each = nrow(b)),],b,row.names = NULL)
    

    这样

    > C
      city detail city.1 detail.1
    1    a      1      x        5
    2    a      1      y        6
    3    b      2      x        5
    4    b      2      y        6
    5    c      3      x        5
    6    c      3      y        6
    

    【讨论】:

      【解决方案3】:

      使用base R,我们可以使用merge

      merge(setNames(a, paste0(names(a), ".a")), b)
      #   city.a detail.a city detail
      #1      a        1    x      5
      #2      b        2    x      5
      #3      c        3    x      5
      #4      a        1    y      6
      #5      b        2    y      6
      #6      c        3    y      6
      

      【讨论】:

        猜你喜欢
        • 2017-06-06
        • 2021-02-06
        • 1970-01-01
        • 1970-01-01
        • 2015-08-18
        • 2019-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多