基于列合并文件

时间:2014-10-04 19:25:42

标签: r merge

我有多个文件,包含许多行和三列,需要在前两列匹配的基础上合并它们。文件1

12   13   a
13   15   b
14   17   c
 4    9   d
 .    .   .
 .    .   .
 81   23  h

文件2

12   13   e
3    10   b
14   17   c
 4    9   j
 .    .   .
 .    .   .
 1   2    k

档案3

12   13   m
13   15   k
1     7   x
24    9   d
 .    .   .
 .    .   .
 1   2    h

等等。 我想合并它们以获得以下结果

12   13   a  e  m
13   15   b  k
14   17   c  c
 4    9   d  j
 3   10   b
24    9   d
 .    .   .
 .    .   .
 81   23  h
  1    2  k
  1    7  x

1 个答案:

答案 0 :(得分:1)

对于这些类型的问题,通常会想到的第一件事是merge,可能与Reduce(function(x, y) merge(x, y, by = "somecols", all = TRUE), yourListOfDataFrames)一起使用。

然而,merge并不总是最有效的功能,特别是因为它看起来像你想要"崩溃"从左到右填充行的所有值,这不是默认的merge行为。

相反,我建议您将所有内容堆叠成一个长data.frame并在添加索引变量后重新整形。

以下是两种方法:

选项1:" dplyr" +" tidyr"

  1. 使用mget将您的所有data.frame放入list
  2. 使用rbind_alllist转换为单个data.frame
  3. 使用sequence(n())中的mutate来自" dplyr"分组数据并创建索引。
  4. 使用来自" tidyr"的spread转变为长期"格式为"宽"格式。
  5. library(dplyr)
    library(tidyr)
    
    combined <- rbind_all(mget(ls(pattern = "^file\\d")))
    combined %>%
      group_by(V1, V2) %>% 
      mutate(time = sequence(n())) %>% 
      ungroup() %>% 
      spread(time, V3, fill = "")
    # Source: local data frame [7 x 5]
    # 
    #   V1 V2 1 2 3
    # 1  1  7 x    
    # 2  3 10 b    
    # 3  4  9 d j  
    # 4 12 13 a e m
    # 5 13 15 b k  
    # 6 14 17 c c  
    # 7 24  9 d  
    

    选项2:&#34; data.table&#34;

    1. 使用mget将您的所有data.frame放入list
    2. 使用rbindlist将该列表转换为单个data.table
    3. 使用sequence(.N)按群组生成序列。
    4. 使用dcast.data.table转换&#34; long&#34; data.table进入广泛的&#34;之一。
    5. library(data.table)
      
      dcast.data.table(
        rbindlist(mget(ls(pattern = "^file\\d")))[, 
          time := sequence(.N), by = list(V1, V2)],
        V1 + V2 ~ time, value.var = "V3", fill = "")
      #    V1 V2 1 2 3
      # 1:  1  7 x    
      # 2:  3 10 b    
      # 3:  4  9 d j  
      # 4: 12 13 a e m
      # 5: 13 15 b k  
      # 6: 14 17 c c  
      # 7: 24  9 d    
      

      这两个答案都假设我们从以下示例数据开始:

      file1 <- structure(
        list(V1 = c(12L, 13L, 14L, 4L), V2 = c(13L, 15L, 17L, 9L), 
             V3 = c("a", "b", "c", "d")), .Names = c("V1", "V2", "V3"), 
        class = "data.frame", row.names = c(NA, -4L))
      file2 <- structure(
        list(V1 = c(12L, 3L, 14L, 4L), V2 = c(13L, 10L, 17L, 9L), 
             V3 = c("e", "b", "c", "j")), .Names = c("V1", "V2", "V3"), 
        class = "data.frame", row.names = c(NA, -4L))
      file3 <- structure(
        list(V1 = c(12L, 13L, 1L, 24L), V2 = c(13L, 15L, 7L, 9L), 
             V3 = c("m", "k", "x", "d")), .Names = c("V1", "V2", "V3"), 
        class = "data.frame", row.names = c(NA, -4L))