【发布时间】:2021-09-02 17:13:19
【问题描述】:
我有以下data.frame:
第一列包含(基因的)名称,第 2-4 列包含三个重复中一个条件的计数,第 5-7 列包含三个重复中第二个条件的计数。 现在,我想过滤掉所有的基因,那个
- 3 次重复中有 2 次至少有值(一个值可以为 0 或缺失)
- 每个条件的计数 ≥ 3
这是我的数据:
test = read.table(text="Geneid exp1 exp2 exp3 stat1 stat2 stat3
gene_0001 12 11 18 115 103 97
gene_0002 1 2 0 18 21 20
gene_0003 3 3 0 3 0 0
gene_0004 1 1 0 1 2 0
gene_0005 50 0 0 20 0 0
gene_0006 0 0 1 1 0 0
gene_0007 0 2 3 0 2 3", header=TRUE, row.names=1)
我通过创建一个二进制矩阵开始这样做,并使用dplyr过滤我的数据:
bin_data <- test
bin_data[bin_data == 0] <- NA
idx <- is.na(bin_data)
bin_data[!idx] <- 1
bin_data[idx] <- 0
# Now, I make a second data.frame out of my columnnames, so that I have the information of condition and replicate number:
my_columns=data.frame(row.names=as.vector(colnames(test)), as.vector(colnames(test)))
colnames(my_columns) = "condition"
my_columns$label = my_columns$condition
my_columns$ID = my_columns$condition
my_columns$replicate = substr(my_columns$condition, nchar(my_columns$condition)-1+1, nchar(my_columns$condition))
my_columns$condition = substr(my_columns$condition,1,nchar(my_columns$condition)-1)
my_columns$condition = as.factor(my_columns$condition)
# Now comes the actual filtering:
keep <- bin_data %>%
data.frame() %>%
rownames_to_column() %>%
gather(ID, value, -rowname) %>%
left_join(., data.frame(my_columns), by = "ID") %>%
group_by(rowname, condition) %>%
summarize(miss_val = n() - sum(value)) %>%
filter(miss_val <= 1) %>% # in two out of three replicates
spread(condition, miss_val)
test2 <- test[keep$rowname, ]
# Now I filter my data that so that there are at least 3 counts
test2 %>%
filter_all(., any_vars(. >= 3))
然而,在最后一步中,它没有考虑组(“条件”),因为否则gene_0007 不会被过滤掉。如何让它考虑 ≥3 PER 条件?
这是我的预期输出:
【问题讨论】:
-
仅供参考,“第一列包含名称” 很棒,但使用
row.names=1会通过将Geneid的列转换为row.names来打破这一点。不是一回事。 -
gene_0007的 exp 为0,2,3,stat 为0,2,3;这两个条件都有 2 个或多个大于 0 的值,并且每个值的总和都大于 3。为什么它不在您的预期输出中? -
仅供参考,
tidyr已从gather/spread转移到pivot_*功能;它们更强大,值得迁移您的肌肉记忆和过程。 -
这不是关于总和,而是每个条件的复制的每个值。它被过滤掉了,因为在根据我的第一条规则过滤后,两个副本中的一个小于 3。感谢您指出“tidyr”,我会检查一下!
-
您的第一条规则是“至少有 3 个值中的 2 个”:0007 有 2 个非零值,所以应该不错。我是怎么误解的?