2014-01-19 27 views
0

我有一个巨大的.csv文件是这样的:如何从混合和凌乱的CSV文件构建数据矩阵?

Transcript Id Gene Id(name) Mirna Name miTG score 
ENST00000286800 ENSG00000156273 (BACH1) hsa-let-7a-5p 1 
UTR3 21:30717114-30717142 0.05994568 
UTR3 21:30717414-30717442 0.13591267 
ENST00000345080 ENSG00000187772 (LIN28B) hsa-let-7a-5p 1 
UTR3 6:105526681-105526709 0.133514751 

,我想从它建立这样一个矩阵:

Transcript Id Gene Id(name) Mirna Name  miTG score UTR3  MRE_score 
ENST00000286800 ENSG00000156273 (BACH1) hsa-let-7a-5p  1 21:30717414-30717442 0.13591267 

我要添加三个新列进我叫UTR3新的矩阵,和CDS

Gene ID(例如ENST00000286800),也有在原有的矩阵数UTR3(这里有两个UTR3的对ENST00000286800,和一个UTR3ENST00000345080)我们选择UTR3在第三列中的最高分。在新矩阵中,每Gene IDUTR3的值将是原始矩阵第二列中UTR3的值。

任何机构能帮助我重塑这些数据并构建我的新矩阵吗?

+0

你陷入了相当痛苦的境地;责任在于什么或者谁创建了“csv”文件。你对创建它的过程有任何控制吗?修复它听起来像是一个更好的主意(如果可以的话)。如果是这样,我们可以告诉你该文件应该是什么样子,这样你就可以使用'read.csv'轻松加载它,并筛选出最好的'UTR3'记录基因。 – flodel

+0

不,别人创造它,我对它没有任何控制! P – user2806363

回答

3

你可以尝试使用正则表达式结构CSV:

textfile <- "ENST00000286800 ENSG00000156273 (BACH1) hsa-let-7a-5p 1 
UTR3 21:30717114-30717142 0.05994568 
UTR3 21:30717414-30717442 0.13591267 
ENST00000345080 ENSG00000187772 (LIN28B) hsa-let-7a-5p 1 
UTR3 6:105526681-105526709 0.133514751" 
txt <- readLines(textConnection(textfile)) 

sepr <- grepl("^ENST.*", txt) 
r <- rle(sepr) 
r <- r$lengths[!r$values] 

regex <- "(\\S+)\\s+(\\S+)\\s(\\([^)]+\\)\\s+\\S+)\\s+(\\d+)" 
m <- regexec(regex, txt[sepr]) 
m1 <- as.data.frame(t(sapply(regmatches(txt[sepr], m), "[", 2:5))) 
m1 <- m1[rep(1:nrow(m1), r),] 

regex <- "(\\S+)\\s+(\\S+)\\s+(\\S+)" 
m <- regexec(regex, txt[!sepr]) 
m2 <- as.data.frame(t(sapply(regmatches(txt[!sepr], m), "[", 2:4))) 

df <- cbind(m1, m2[,-1]) 
names(df) <- c("Transcript Id", "Gene Id(name)", "Mirna Name",  "miTG score", "UTR3",  "MRE_score" ) 
rownames(df) <- NULL 
df 
# Transcript Id Gene Id(name)    Mirna Name miTG score     UTR3 MRE_score 
# 1 ENST00000286800 ENSG00000156273  (BACH1) hsa-let-7a-5p   1 21:30717114-30717142 0.05994568 
# 2 ENST00000286800 ENSG00000156273  (BACH1) hsa-let-7a-5p   1 21:30717414-30717442 0.13591267 
# 3 ENST00000345080 ENSG00000187772 (LIN28B) hsa-let-7a-5p   1 6:105526681-105526709 0.133514751 
1

使用这个测试数据:

Lines <- " Transcript Id Gene Id(name) Mirna Name miTG score 
ENST00000286800 ENSG00000156273 (BACH1) hsa-let-7a-5p 1 
UTR3 21:30717114-30717142 0.05994568 
UTR3 21:30717414-30717442 0.13591267 
ENST00000345080 ENSG00000187772 (LIN28B) hsa-let-7a-5p 1 
UTR3 6:105526681-105526709 0.133514751" 

读这一切,并设置名称,nms的输出。然后使用累计和计算分组向量,cs。非重复项是每个组的第一行,重复项是以下行。通过集团合并这两套行的各组中提取出的最高:

DF <- read.table(text = Lines, header = TRUE, fill = TRUE, as.is = TRUE, 
     check.names = FALSE) 
nms <- c("cs", names(DF)[1:5], "UTR3", "MRE_score") # out will have these names 
DF$cs <- cumsum(!is.na(DF$Mirna)) # groups each ENST row with its UTR3 rows 
dup <- duplicated(DF$cs) # FALSE for ENST rows and TRUE for UTR3 rows 
both <- merge(DF[!dup, ], DF[dup, ], by = "cs")[c(1:6, 11:12)] # merge ENST & UTR3 rows 
names(both) <- nms 
both$MRE_score <- as.numeric(both$MRE_score) 
Rank <- function(x) rank(x, ties.method = "first") 
out <- both[ave(-both$MRE_score, both$cs, FUN = Rank) == 1, -1] # only keep largest score 

在这里,我们得到:

> out 
     Transcript    Id  Gene  Id(name) Mirna     UTR3 MRE_score 
2 ENST00000286800 ENSG00000156273 (BACH1) hsa-let-7a-5p  1 21:30717414-30717442 0.1359127 
3 ENST00000345080 ENSG00000187772 (LIN28B) hsa-let-7a-5p  1 6:105526681-105526709 0.1335148 

注意的问题是指CDS列,但它是什么,是没有描述,也没有出现在示例输出中,所以我们忽略了它。