【问题标题】:How to rbind several named dataframes but keep only common columns?如何 rbind 几个命名数据框但只保留公共列?
【发布时间】:2020-12-29 13:07:15
【问题描述】:

我在命名空间中有几个名为 a32、a33、...、a63 的数据帧,我必须将它们绑定到单个数据帧。每个都有几个(大约 20 个)列。他们应该有共同的列名,但不幸的是有一些列丢失了。当我尝试 rbind 时,这会导致错误。

l <- 32:63
l<- as.character(l)       ## create a list of characters

A <- do.call(rbind.data.frame,mget(paste0("a",l))) ## "colnames not matching" error

Error in (function (..., deparse.level = 1, make.row.names = TRUE, stringsAsFactors = default.stringsAsFactors(),  : 
  numbers of columns of arguments do not match

我想通过只使用公共列来绑定它们。我尝试在 for 循环中使用 paste0 来列出所有数据框的列名,并查看哪些数据框缺少列但无处可去。如何通过一一列出每个数据框的列名来避免手动搜索丢失的列。

举个小例子,说:

a32 <- data.frame(AB = 1, CD = 2, EF = 3, GH = 4)
a33 <- data.frame(AB = 6,         EF = 7)
a34 <- data.frame(AB = 8, CD = 9, EF = 10, GH = 11)
a35 <- data.frame(AB = 12,CD = 13,        GH = 14)
a36 <- data.frame(AB = 15,CD = 16,EF = 17,GH = 18)
and so on

有没有一种有效的方法来 rbind 命名空间中的所有 32 个数据帧?

【问题讨论】:

标签: r dataframe rbind


【解决方案1】:
  • 获取列表中的数据帧。
  • 使用Reduce + intersect 找出常用列
  • 使用公共列将列表中的每个数据框设置为子集
  • 将所有数据组合在一起。
list_data <- mget(paste0("a",l))
common_cols <- Reduce(intersect, lapply(list_data, colnames))
result <- do.call(rbind, lapply(list_data, `[`, common_cols))

您也可以使用purrr::map_df,这将缩短此时间。

result <- purrr::map_df(list_data, `[`, common_cols)

【讨论】:

    【解决方案2】:

    基础 R 解决方案:

    # get names from workspace
    dat_names <- ls()[grepl("a[0-9][0-9]", ls())]
    
    # get data
    df <- lapply(dat_names, get)
    
    # get comman col
    commen_col <- Reduce(intersect, sapply(df, FUN = colnames, simplify = TRUE))
    
    # selet and ribind
    dat <- lapply(df, FUN = function(x, commen_col) x[, c(commen_col)], commen_col=commen_col)
    dat <- do.call("rbind", dat)
    colnames(dat) <- commen_col
    dat
    
    # AB
    # [1,]  1
    # [2,]  6
    # [3,]  8
    # [4,] 12
    # [5,] 15
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      • 2017-09-04
      相关资源
      最近更新 更多