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

时间:2015-12-09 07:23:53

标签: regex r frequency

我有一个数据帧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

Attn:akrun

以下是我们拥有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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

我们split带有分隔符:的'df'的第2和第3列,使用cSplit中的splitstackshape转换为'long'格式。输出将是data.table。我们使用melt重新整形,方法是选择'id.var'作为'sample',同时删除NA值。通过'sample','variable'和'value'分组,我们得到行数(.N),通过paste'value'和'N'创建新变量和序列变量('ind')。然后,我们dcast从'long'到'wide'格式。

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))