计算tsv文件不同部分中由分隔符分隔的字符串的频率



我有一个数据帧mydf,其中左右基因用":"分隔。我需要计算每个文件中LeftGeneRightGene列中这些基因的出现次数,并得到类似的结果。在R中,最好的方法是什么?

sample     LeftGene    RightGene
file1
           ATT:TAA
           ATT:ATT      ATT
file2      
           TTP:TTG      TTP:TTP

结果

file1
LeftGene           RightGene
ATT=3              ATT=1
TAA=1
file2
LeftGene           RightGene
TTP=1              TTP=2
TTG=1

收件人:akrun

这是实际数据的dput,其中我们有file_name,需要获得每个文件中Left.Gene.SymbolsRight.Gene.Symbols的频率。我也想从所有文件中看到这些基因的频率(累积)。谢谢你的帮助。

mydf<-structure(c("AMLM12001KP", NA, "1114002", NA, NA, NA, NA, NA, 
"1121501", NA, NA, NA, "NA", "NA", "NA", "NA", "CR1L", "GIGYF2:GIGYF2:GIGYF2:ENPP3", 
"NA", "NA", "NA", "NA", "NTNG1:NTNG1:ENPP3", "NA", "NA", "NA", 
"NA", "NA", "CDC27:CDC27", "NA", "ENPP3", "NA", "NA", "NA", "NA", 
"NA"), .Dim = c(12L, 3L), .Dimnames = list(NULL, c("files_name", 
"Left.Gene.Symbols", "Right.Gene.Symbols")))

预期输出:

AMLM12001KP
Left.Gene.Symbols       Right.Gene.Symbols
1114002
Left.Gene.Symbols       Right.Gene.Symbols
CR1L=1                  CDC27=2
GIGYF2=3                ENPP3=1
ENPP3=1
1121501
Left.Gene.Symbols       Right.Gene.Symbols
NTNG1=2 
ENPP3=1
All files
Left.Gene.Symbol        Right.Gene.Symbols
CR1L=1                  CDC27=2
GIGYF2=3                ENPP3=1
NTNG1=2 
ENPP3=2
编辑
dd2<-structure(c("AMLM12001KP", NA, "1114002", NA, NA, NA, NA, NA,"1121501", NA, NA, NA, "NA", "NA", "NA", "NA", "CR1L", "GIGYF2:GIGYF2:GIGYF2:ENPP3","NA", "NA", "NA", "NA", "NTNG1:NTNG1:ENPP3", "NA", "NA", "NA","NA", "NA", "CDC27:CDC27", "NA", "ENPP3", "NA", "NA", "NA", "NA", "NA"), .Dim = c(12L, 3L), .Dimnames = list(NULL, c("files_name", "Left.Gene.Symbols", "Right.Gene.Symbols")))

## change character NAs to <NA> and carry-forward the file column
dd2[dd2 == 'NA'] <- NA
dd2[, 1] <- na.omit(unique(dd2[, 1]))[cumsum(!is.na(dd2[, 1]))]
## split based on file name
sp <- split(data.frame(dd2, stringsAsFactors = FALSE), dd2[, 1])
## split each string by `:` and make a table
(l <- lapply(sp, function(x) {
  x <- droplevels(x[, -1])
  f <- function(x) na.omit(unlist(strsplit(x, ':')))
  left <- f(x[, 1])
  right <- f(x[, 2])
  table(c(left, right), rep(names(x), c(length(left), length(right))))
}))
# $`1114002`
# 
#          Left.Gene.Symbols Right.Gene.Symbols
#   CDC27                  0                  2
#   CR1L                   1                  0
#   ENPP3                  1                  1
#   GIGYF2                 3                  0
# 
# $`1121501`
# 
#         Left.Gene.Symbols
#   ENPP3                 1
#   NTNG1                 2
# 
# $AMLM12001KP
# < table of extent 0 x 0 >

由于每个列表元素都是一个表,因此将它们作为表进行处理

data.frame(l$`1114002`)
#     Var1               Var2 Freq
# 1  CDC27  Left.Gene.Symbols    0
# 2   CR1L  Left.Gene.Symbols    1
# 3  ENPP3  Left.Gene.Symbols    1
# 4 GIGYF2  Left.Gene.Symbols    3
# 5  CDC27 Right.Gene.Symbols    2
# 6   CR1L Right.Gene.Symbols    0
# 7  ENPP3 Right.Gene.Symbols    1
# 8 GIGYF2 Right.Gene.Symbols    0

这是列表格式的另一种方式

rl <- readLines(textConnection("
sample     LeftGene    RightGene
file1
           ATT:ATT      ATT
file2      
           TTP:TTG      TTP:TTP
"))
dd <- setNames(read.table(text = rl[grep('file', rl) + 1], stringsAsFactors = FALSE),
               c('LeftGene','RightGene'))
rownames(dd) <- paste0('File', 1:nrow(dd))
setNames(lapply(1:nrow(dd), function(x) {
  sp <- strsplit(unlist(dd[x, ]), ':')
  table(unlist(sp), rep(names(sp), lengths(sp)))
}), rownames(dd))
# $File1
#     
#       LeftGene RightGene
#   ATT        2         1
#
# $File2
#      
#       LeftGene RightGene
#   TTG        1         0
#   TTP        1         2

setNames(lapply(1:nrow(dd), function(x) {
  sp <- strsplit(unlist(dd[x, ]), ':')
  lapply(sp, function(y) data.frame(table(y)))
}), rownames(dd))

# $File1
# $File1$LeftGene
#     y Freq
# 1 ATT    2
# 
# $File1$RightGene
#     y Freq
# 1 ATT    1
# 
# 
# $File2
# $File2$LeftGene
#     y Freq
# 1 TTG    1
# 2 TTP    1
# 
# $File2$RightGene
#     y Freq
# 1 TTP    2

我们用分隔符: split"df"的第二列和第三列,用cSplitsplitstackshape转换为"long"格式。输出将是data.table。我们使用melt通过选择"id.var"作为"sample"来再次重塑它,同时删除NA值。按"sample"、"variable"one_answers"value"分组,我们得到行数(.N),通过paste使用"value"one_answers"N"以及序列变量("d")创建新变量。然后,我们将dcast从"长"格式转换为"宽"格式。

library(splitstackshape)
library(data.table)
dM <- melt(cSplit(df, 2:3, ':', 'long'),
         id.var='sample', na.rm=TRUE)[, .N,.(sample, variable, value)]
dM[, valueN:= paste(value, N, sep="=")]
dM[, ind:= 1:.N, .(sample, variable)]
dcast(dM, ind+sample~variable, value.var='valueN')
#   ind sample LeftGene RightGene
#1:   1  file1    ATT=2     ATT=1
#2:   1  file2    TTP=1     TTP=2
#3:   2  file2    TTG=1        NA

数据

df <- structure(list(sample = c("file1", "file2"),
 LeftGene = c("ATT:ATT", 
"TTP:TTG"), RightGene = c("ATT", "TTP:TTP")), 
.Names = c("sample", 
"LeftGene", "RightGene"), class = "data.frame", 
row.names = c(NA, -2L))

最新更新