合并具有不同行号的文件

时间:2015-09-25 08:13:26

标签: r merge

我有多个看起来像这样的文件:

文件1:

rsRNA-2312-n     2
rsRNA-6508-n     2
rsRNA-6382-n    10
rsRNA-951-n      0
rsRNA-6330-n     4
rsRNA-6330-n    11
rsRNA-1385-n     3
rsRNA-4945-n     0
rsRNA-946-n      9

file2的:

rsRNA-552-n      2
rsRNA-5301-n     7
rsRNA-6487-n     0
rsRNA-4945-n     7
rsRNA-2445-n     9
rsRNA-6490-n     2

file3的:

rsRNA-4946-n     1
rsRNA-5058-n     0
rsRNA-552-n      0
rsRNA-849-n      2
rsRNA-3302-n     2
rsRNA-4099-n     0
rsRNA-552-n      1

我想合并创建输出的文件,该输出在单独的列中包含每个输入文件的值,并在column1中合并唯一标识符(输入文件中的第1列)。如果在特定输入文件中找不到标识符,则此特定输入的此标识符的计数应为0。

输出(非真实数据):

identifier   file1   file2   file3
rsRNA-552-n      2       4       5
rsRNA-5301-n     7      12       2
rsRNA-6487-n     0       1       5
rsRNA-4945-n     7      12       1
rsRNA-2445-n     9       4      55
rsRNA-6490-n     2       1       0

正在尝试:

files <- list.files(path = "./bowtie_mapped/", pattern='rsRNA_N1_grep_cut_cutN1_grep_cut_N1_grep2_N1_grep_N1*')

merged.data.frame = Reduce(function(...) merge(..., all=T), files)

do.call(rbind, lapply(files,
                      function(f) {
                        cbind(read.csv(f), file_name=f)
                      }))

2 个答案:

答案 0 :(得分:3)

如果名称仅在文件中出现一次,则执行以下操作:

library(data.table)
# make a list of filenames
file.list <- list.files(path = "./bowtie_mapped/", pattern='rsRNA*')
# read all the files
df.list <- lapply(file.list, read.csv)
dt <- rbindlist(df.list, idcol = "id")

dtnew <- dcast(dt, V1 ~ id, value.var = "V2", fun.aggregate = sum, fill = 0)

这导致:

              V1  1 2 3
 1: rsRNA-1385-n  3 0 0
 2: rsRNA-2312-n  2 0 0
 3: rsRNA-2445-n  0 9 0
 4: rsRNA-3302-n  0 0 2
 5: rsRNA-4099-n  0 0 0
 6: rsRNA-4945-n  0 7 0
 7: rsRNA-4946-n  0 0 1
 8: rsRNA-5058-n  0 0 0
 9: rsRNA-5301-n  0 7 0
10:  rsRNA-552-n  0 2 1
11: rsRNA-6330-n 15 0 0
12: rsRNA-6382-n 10 0 0
13: rsRNA-6487-n  0 0 0
14: rsRNA-6490-n  0 2 0
15: rsRNA-6508-n  2 0 0
16:  rsRNA-849-n  0 0 2
17:  rsRNA-946-n  9 0 0
18:  rsRNA-951-n  0 0 0

使用dplyr / tidyr组合可以获得相同的结果:

library(dplyr)
library(tidyr)
dfnew <- bind_rows(file.list, .id = "id") %>% 
  group_by(id, V1) %>% 
  summarise(V2=sum(V2)) %>% 
  spread(id, V2, fill=0)

答案 1 :(得分:1)

这是一个预处理数据的解决方案。

您可以使用已经找到的Reduce / merge-solution进行预处理数据

使用合并:

alldata <- lapply(files, function(x){
  #read in data
  data <- read.table(text=x,header=F,stringsAsFactors=F)
  #aggregate data
  data2 <- dcast(V1~"value",value.var="V2",fun.agg=sum,data=data)
  return(data2)
})

res <- Reduce(function(x,y) merge(x,y, by="V1",all=TRUE), alldata)

如果您想要更多地控制特定值的来源,您还可以使用带文件标识符的重塑。请注意,在合并解决方案中,我迭代了文件,这里我迭代文件名。

#create a long dataframe including an origin
alldata <- do.call(rbind,lapply(names(files), function(x){
  #read in data
  data <- read.table(text=files[[x]],header=F,stringsAsFactors=F)
  #aggregate data
  data2 <- dcast(V1~"value",value.var="V2",fun.agg=sum,data=data)
  data2$origin <- x
  return(data2)
})
)

res <- dcast(V1~origin,value.var="value",data=alldata)

使用的数据:文本字符串列表

files <- structure(list(file1 = "rsRNA-2312-n     2\nrsRNA-6508-n     2\nrsRNA-6382-n    10\nrsRNA-951-n      0\nrsRNA-6330-n     4\nrsRNA-6330-n    11\nrsRNA-1385-n     3\nrsRNA-4945-n     0\nrsRNA-946-n      9", 
    file2 = "rsRNA-552-n      2\nrsRNA-5301-n     7\nrsRNA-6487-n     0\nrsRNA-4945-n     7\nrsRNA-2445-n     9\nrsRNA-6490-n     2", 
    file3 = "rsRNA-4946-n     1\nrsRNA-5058-n     0\nrsRNA-552-n      0\nrsRNA-849-n      2\nrsRNA-3302-n     2\nrsRNA-4099-n     0\nrsRNA-552-n      1"), .Names = c("file1", 
"file2", "file3"))