我有一个数据帧mydf
,其中左和右基因用':'分隔。我需要计算每个文件LeftGene
和RightGene
列中这些基因的出现次数,并得到类似结果的结果。 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.Symbols
和Right.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
答案 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))