【问题标题】:R rbind while preserving order or rows in each data frameR rbind 同时保留每个数据帧中的顺序或行
【发布时间】:2019-02-14 08:41:36
【问题描述】:

我需要合并 2 个数据帧,同时保留它们在每个数据帧中的出现顺序:

x = data.frame(a=1:3, b=2:4, c=3:5)
y = data.frame(a=c(10, 20, 30), b=c(20, 30, 40), c=c(30, 40, 50))

我想要的是:

> z 

a   b   c
1   2   3
10  20  30
2   3   4
20  30  40
3   4   5
30  40  50

但 rbind 所做的是将第二个数据帧添加到第一个数据帧下。

【问题讨论】:

  • 两者总是有相同的行数?

标签: r rbind


【解决方案1】:

试试这个单线

do.call("rbind", Map("rbind", split(x, 1:nrow(x)), split(y, 1:nrow(y))))

如果xy 与问题相同,则给出此data.frame:

      a  b  c
1.1   1  2  3
1.2  10 20 30
2.2   2  3  4
2.21 20 30 40
3.3   3  4  5
3.31 30 40 50

它逐行拆分每个数据帧,然后将 rbind 拆分的相应组件。然后它会重新绑定所有这些。请注意,即使列具有不同的类型,这种单行也可以工作。例如,即使:

x <- data.frame(a = letters[1:3], b = 1:3, c = c(TRUE, FALSE, TRUE))
y <- data.frame(a = LETTERS[1:3], b = 11:13, c = c(FALSE, TRUE, FALSE))

【讨论】:

    【解决方案2】:

    作为另一个基础 r 版本:

    x = data.frame(a=1:3, b=2:4, c=3:5)
    y = data.frame(a=c(10, 20, 30), b=c(20, 30, 40), c=c(30, 40, 50))
    
    mapply(FUN = function(i,j){rbind(i,j)}, x, y)
    #>       a  b  c
    #> [1,]  1  2  3
    #> [2,] 10 20 30
    #> [3,]  2  3  4
    #> [4,] 20 30 40
    #> [5,]  3  4  5
    #> [6,] 30 40 50
    

    reprex package (v0.2.1) 于 2019 年 2 月 14 日创建

    【讨论】:

      【解决方案3】:

      您可以使用来自 Paweł 在 base R 中的行号概念:

      x$rowid <- seq(1, nrow(x)*2, by = 2) # or simply 1:nrow(x)
      y$rowid <- seq(2, nrow(y)*2, by = 2)
      z <- rbind(x, y)
      z[order(z$rowid),]
      
         a  b  c rowid
      1  1  2  3     1
      4 10 20 30     2
      2  2  3  4     3
      5 20 30 40     4
      3  3  4  5     5
      6 30 40 50     6
      

      edit 也可以使用 rbind() 生成的行名:

      z <- do.call(rbind, list(x = x, x = y))
      z[order(rownames(z)), ]
      
            a  b  c
      x.1   1  2  3
      x.11 10 20 30
      x.2   2  3  4
      x.21 20 30 40
      x.3   3  4  5
      x.31 30 40 50
      

      【讨论】:

        【解决方案4】:

        您应该在每个数据框中添加行号变量,并在绑定后按此变量排序。使用dplyr,您可以这样做:

        library(dplyr)
        
        x %>%
          mutate(rn = row_number()) %>%
          bind_rows(
            y %>%
              mutate(rn = row_number())
          ) %>%
          arrange(rn)%>%
          select(-4)
        

        【讨论】:

          【解决方案5】:

          为了完整起见,也是data.table的解决方案。

          library(data.table)
          dt.x <- data.table(x)
          dt.y <- data.table(y)
          dt.x[,Row.Num :=seq(1:.N)]
          dt.y[,Row.Num :=seq(1:.N)]
          rbindlist(list(dt.x,dt.y), idcol = TRUE)[order(Row.Num),]
          

          【讨论】:

            猜你喜欢
            • 2020-06-22
            • 2013-01-25
            • 1970-01-01
            • 2017-08-08
            • 2019-11-05
            • 2021-09-08
            • 1970-01-01
            • 2021-05-12
            • 2023-03-20
            相关资源
            最近更新 更多