【问题标题】:Subsetting a data frame based on another data frame with multiple conditions基于具有多个条件的另一个数据框对数据框进行子集化
【发布时间】:2018-05-08 04:21:24
【问题描述】:

我有一个甲基化数组数据框列表,如下所示,名为betatable

sample_A sample_B ... chr    position
0.5      0.3          chr1   75939
0.3      0.6          chr2   11195
...

我想根据 chr 的特定条件和位置范围对上述数据框进行子集化并生成另一个数据框。 为此,我还有另一组数据genes_pos

gene   chr    range_lower   range_upper
ABC    chr1   34959         69593
...

我正在考虑使用lapply,但无法弄清楚。 非常感谢。

【问题讨论】:

  • 如果你能创建一个minimal reproducible example,那将对我们有所帮助。或者在你的代码上使用dput()打印出结构,然后在这里打印出来。

标签: r dataframe


【解决方案1】:

一种方法是使用非等连接

但是,now deleted post 中 OP 提供的样本数据集需要准备,因为位置是作为因子而不是整数给出的

library(data.table)
# prepare data
setDT(betatable, keep.rownames = "sample.id")
setDT(gene_pos)
# coerce positions from factor to integer
betatable[, pos := as.integer(as.character(pos))]
cols <- c("lower", "upper")
gene_pos[, (cols) := lapply(.SD, function(x) as.integer(as.character(x))), .SDcols = cols]

# non-equi join
betatable[gene_pos, on = .(chr, pos >= lower, pos <= upper), gene := i.gene][!is.na(gene)]
   sample.id probe  chr pos  gene
1:  sample_a   111 chr1 335 geneA
2:  sample_c   200 chr2 221 geneB
3:  sample_e   228 chr2 230 geneC

OP 提供的数据

column <-c("probe","chr","pos")
sample_a <- c("111","chr1","335")
sample_b <- c("115","chr1","380")
sample_c <- c("200","chr2","221")
sample_d <- c("222","chr2","226")
sample_e <- c("228","chr2","230")
betatable <-data.frame(rbind(sample_a,sample_b,sample_c,sample_d,sample_e))
colnames(betatable)<- column

gene_A <- c("geneA","chr1", "120","336")
gene_B <- c("geneB","chr2", "200","222")
gene_C <- c("geneC","chr2", "227","231")
gene_pos <- rbind(gene_A,gene_B,gene_C)
gene_pos <- data.frame(rbind(gene_A,gene_B,gene_C))
colnames(gene_pos)<-c("gene","chr","lower","upper")

betatable
         probe  chr pos
sample_a   111 chr1 335
sample_b   115 chr1 380
sample_c   200 chr2 221
sample_d   222 chr2 226
sample_e   228 chr2 230
gene_pos
        gene  chr lower upper
gene_A geneA chr1   120   336
gene_B geneB chr2   200   222
gene_C geneC chr2   227   231

【讨论】:

    【解决方案2】:

    在本例中,您可以使用 dplyr::inner_join

    可重现的例子:

    set.seed(123)
    x <- data.frame(x = sample(1:100, 100, replace = TRUE), y = sample(1:100, 100, replace = TRUE), chr = sample(c("chr1", "chr2", "chr3"), 100, replace = T), Position = sample(1:10000, 100, replace = TRUE))
    genes <- data.frame(gene = c("gene1", "gene2", "gene3"), chr = c("chr1", "chr2", "chr3"), rangelower = c(1, 3000, 6000), rangeupper = c(2999, 5999, 10001))
    

    inner join,然后过滤上下限

    library(dplyr)
    
    new_df <- x %>% 
                   inner_join(genes, by = "chr") %>% 
                   filter(Position < rangeupper, Position > rangelower)
    

    查看结果:

    > head(new_df)
        x  y  chr Position  gene rangelower rangeupper
    1  90 61 chr1       83 gene1          1       2999
    2  96 94 chr2     3896 gene2       3000       5999
    3  90 15 chr3     8029 gene3       6000      10001
    4  96 41 chr3     8569 gene3       6000      10001
    5 100 22 chr3     7040 gene3       6000      10001
    6  66 37 chr1     1039 gene1          1       2999 
    

    然后我们可以按基因拆分数据帧。

    list_dfs <- split(new_df, new_df$gene)
    

    【讨论】:

    • 对不起,如果我没有清楚地表达我的问题。我需要使用“gene_pos”中的 chr 和范围信息来对 betatable 进行子集化,因为目标基因很多。
    • 你能给我可重现的代码,以便我可以在 R 中使用它然后回来吗?
    • 感谢您的快速回复!我认为这完美地解决了我的问题!
    • 太棒了!你能帮我一个忙,勾选接受我答案的绿色复选框,然后投票吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-18
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2016-03-19
    • 2013-02-10
    • 1970-01-01
    相关资源
    最近更新 更多