首页 文章

R:合并数据帧列表

提问于
浏览
-1

我是R的总菜鸟,我已经尝试(并重试)寻找以下问题的答案,但我无法得到任何建议的解决方案来做我感兴趣的事情 .

我有两个命名元素列表,每个元素指向具有相同布局的数据框:

(编辑)

df1 <- data.frame(A=c(1,2,3),B=c("A","B","C"))
df2 <- data.frame(A=c(98,99),B=c("Y","Z"))
lst1 <- c(X=df1,Y=df2)
df3 <- data.frame(A=c(4,5),B=c("D","E"))
lst2 <- c(X=df3)

(编辑2)

因此,将多个数据帧存储在列表中似乎是一个坏主意,因为它会将数据帧转换为列表 . 因此,我将寻找另一种存储一组命名数据帧的方法 .

通常,两个元素中元素的名称可能部分,完全或根本不重叠 .

我正在寻找一种方法将两个列表合并为一个列表:

<some-function-sequence>(lst1, lst2)
->
c(X=rbind(df1,df3),Y=df2)
  • 导致这样的事情:

[编辑:语法更改为正确反映所需结果(数据列表框)] $ X A B 1 1 A 2 2 B 3 3 C 4 4 D 5 5 E

$X.B
   A B
1 98 Y
2 99 Z

即:

  • 如果列表包含相同的元素名称,每个名称都指向一个数据帧,那么我想'rbind'来自这两个数据帧的行,并将结果数据帧分配给结果列表中的相同元素名称 .

  • 否则,只应将两个列表中的元素名称和数据帧复制到结果列表中 .

我已经尝试了许多讨论中的解决方案,例如:

任何帮助都将非常感谢!

[解决方案]解决方案似乎是在收集数据帧到 list(...) 时改变 c(...) 的使用,之后皮埃尔提出的解决方案似乎给出了期望的结果 .

2 回答

  • 0

    以下是使用 splitc 组合类似术语的建议解决方案 . 请阅读底部的警告:

    s <- split(c(lst1, lst2), names(c(lst1,lst2))) 
    lapply(s, function(lst) do.call(function(...) unname(c(...)), lst))
    # $X.A
    # [1] 1 2 3 4 5
    # 
    # $X.B
    # [1] "A" "B" "C" "D" "E"
    # 
    # $Y.A
    # [1] 98 99
    # 
    # $Y.B
    # [1] "Y" "Z"
    

    此解决方案基于NOT作为字符串的因素 . 它不会引发错误但会将因子转换为数字 . 下面我将展示如何转换数据以删除因子 . 如果您需要因素,请告诉我:

    df1 <- data.frame(A=c(1,2,3),B=c("A","B","C"), stringsAsFactors=FALSE)
    df2 <- data.frame(A=c(98,99),B=c("Y","Z"), stringsAsFactors=FALSE)
    lst1 <- c(X=df1,Y=df2)
    df3 <- data.frame(A=c(4,5),B=c("D","E"), stringsAsFactors=FALSE)
    lst2 <- c(X=df3)
    

    如果数据存储在列表中,我们可以使用:

    lapply(split(c(lst1, lst2), names(c(lst1,lst2))), function(lst) do.call(rbind, lst))
    
  • 0

    以下解决方案可能不是最有效的方法 . 但是,如果我的问题得到解决,这应该可行;)

    # Example data
    
    # Some vectors
    a <- 1:5
    b <- 3:7
    c <- rep(5, 5)
    d <- 5:1
    
    # Some dataframes, data1 and data3 have identical column names
    data1 <- data.frame(a, b)
    data2 <- data.frame(c, b)
    data3 <- data.frame(a, b)
    data4 <- data.frame(c, d)
    
    # 2 lists
    list1 <- list(data1, data2)
    list2 <- list(data3, data4)
    
    # Loop, wich checks for the dataframe names and rbinds dataframes with the same column names
    final_list <- list1
    used_lists <- numeric()
    
    for(i in 1:length(list1)) {
    
        for(j in 1:length(list2)) {
    
        if(sum(colnames(list1[[i]]) == colnames(list2[[j]])) == ncol(list1[[i]])) {
    
          final_list[[i]] <- rbind(list1[[i]], list2[[j]])
          used_lists <- c(used_lists, j)
    
        }
      }
    }
    
    # Adding the other dataframes, which did not have the same column names
    for(i in 1:length(list2)) {
    
      if((i %in% used_lists) == FALSE) {
    
        final_list[[length(final_list) + 1]] <- list2[[i]]
    
      }
    }
    
    # Final list, which includes all other lists
    final_list
    

相关问题