【问题标题】:rbinding two data frame with same num of columns绑定两个具有相同列数的数据框
【发布时间】:2021-01-03 11:35:35
【问题描述】:

我有两个数据框:

1)

 S     C     V1
"d"   "q"    2
...
 C     R     V2
"u"   "t"    5
...

我想实现这个:

 B     T       V
"d"   "q"      2
...
"u"  "t"       5
...

我怎样才能有效地做到这一点?

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以重命名两个具有相同名称的数据框以将它们组合在一起。

    new_cols <- c('B','T', 'V')
    names(df1) <- new_cols
    names(df2) <- new_cols
    
    result <- rbind(df1, df2)
    

    【讨论】:

    【解决方案2】:

    这是一个基本的 R 解决方案,它不依赖于您想要一起 rbind 的 data.frames 的数量。

    dftmp <- Map(`names<-`, list(df1, df2), list(value = c("B", "T", "V")))
    df_final <- do.call(rbind, dftmp)
    
    df_final
    #  B T V
    #1 d q 2
    #2 u t 5
    

    数据

    df1 <- read.table(text = "
    S     C     V1
    d   q    2
    ", header = TRUE)
    
    df2 <- read.table(text = "
    C     R     V2
    u   t    5
    ", header = TRUE)
    

    【讨论】:

      【解决方案3】:

      您不能 bind_rows 忽略列名。但是你可以创建一个函数来规避这个:

      library(dplyr)
      force_bind <- function(df1, df2, x_names) {
        
          colnames(df2) <- colnames(df1) <- x_names
          bind_rows(df1, df2)
      }
      
      force_bind(df1, df2, c("B", "T", "V"))
      ##   B T V
      ## 1 d q 2
      ## 2 u t 5
      ``
      

      【讨论】:

      • 你从 dplyr 包中获取了函数bind_rows,不是吗?也许我们应该提到额外的包。
      • 是的,因为有人问如何有效地做到这一点。我已经相应地编辑了我的帖子。有关速度比较,请参阅 here
      【解决方案4】:

      对效率的明确要求和 jwarz 对此的评论让我简要比较了 3 个提议的解决方案

      总结

      • bind_rows()approach 是最快的解决方案(如 jwarz 所述),缺点是依赖额外的包。
      • Map() 方法具有灵活的优势,但速度较慢(比 dplyr 慢 35% 以上)。
      • 看来,bind_rows 的速度优势随着更大的数据帧而变得更大。

      代码和结果

      library(dplyr)
      library(microbenchmark, quietly = TRUE)
      
      df1 <- structure(list(S = "d", C = "q", V1 = 2L), 
                       class = "data.frame", row.names = c(NA, -1L))
      df2 <- structure(list(C = "u", R = "t", V2 = 5L), 
                       class = "data.frame", row.names = c(NA, -1L))
      new_cols <- c("B", "T", "V")
      
      solution1 <- function(df1, df2, new_cols) {
        names(df1) <- new_cols
        names(df2) <- new_cols
        return( rbind(df1, df2) )
      }
      
      solution2 <- function(df1, df2, new_cols) {
        dftmp <- Map(`names<-`, list(df1, df2), list(value = new_cols))
        return( do.call(rbind, dftmp) )
      }
      
      solution3 <- function(df1, df2, new_cols) {
        colnames(df2) <- colnames(df1) <- new_cols
        return( bind_rows(df1, df2) )
      }
      
      microbenchmark(
        rbind = solution1(df1, df2, new_cols), 
        Map   = solution2(df1, df2, new_cols),
        dplyr = solution3(df1, df2, new_cols),
        times = 1E4L
      )
      #> Unit: microseconds
      #>   expr  min   lq     mean median   uq     max neval
      #>  rbind 70.8 78.4 87.57165   82.0 88.0  2613.2 10000
      #>    Map 81.3 88.9 99.86045   93.0 99.4 10521.7 10000
      #>  dplyr 53.3 62.8 70.44836   68.3 71.0  2362.6 10000
      
      df1 <- structure(list(S = letters[sample(1:26, 999L, replace = TRUE)], 
                            C = letters[sample(1:26, 999L, replace = TRUE)], 
                            V1 = sample(1:26, 999L, replace = TRUE)), 
                       class = "data.frame", row.names = 1:999)
      df2 <- structure(list(C = letters[sample(1:26, 999L, replace = TRUE)], 
                            R = letters[sample(1:26, 999L, replace = TRUE)], 
                            V2 = sample(1:26, 999L, replace = TRUE)), 
                       class = "data.frame", row.names = 1:999)
      
        microbenchmark(
        rbind = solution1(df1, df2, new_cols),
        Map   = solution2(df1, df2, new_cols),
        dplyr = solution3(df1, df2, new_cols),
        times = 1E4L
      )
      #> Unit: microseconds
      #>   expr   min    lq      mean median     uq    max neval
      #>  rbind 119.5 130.1 140.10275  134.2 141.10 2751.9 10000
      #>    Map 130.4 141.4 153.46169  145.8 152.65 3978.6 10000
      #>  dplyr  58.3  70.8  78.97621   77.8  80.55 2289.1 10000
      

      reprex package (v0.3.0) 于 2021-01-03 创建

      【讨论】:

        猜你喜欢
        • 2017-06-24
        • 1970-01-01
        • 1970-01-01
        • 2020-12-04
        • 2014-02-21
        • 2012-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多