【问题标题】:match all occurrences in data frame匹配数据框中的所有匹配项
【发布时间】:2020-07-30 01:21:24
【问题描述】:

我正在尝试做与这篇文章类似的事情:Extract rows for the first occurrence of a variable in a data frame,但提取所有出现的事件,而不仅仅是第一个。

这是一个简化的例子: 我有这个名为 toDrop 的数据框

Gene   Taxa
123    A
327    B
445    D
557    A
789    E
123    B
557    C

这是我使用 match 的代码,因此只返回第一个匹配项。我在一个循环中运行它,所以为了简单起见在这里修改。

Gene <- c("123", "327", "445", "557", "789", "123", "557")
Taxa <- c("A", "B", "D", "A", "E", "B", "C")
toDrop <- data.frame(Gene, Taxa)
Temp <- list()
geneNameTemp <- "123"
toDrop[match(geneNameTemp, toDrop$Gene), 2] -> Temp

在此示例中,Temp 应返回“A”和“B”的列表 我想我需要像this post 那样使用 lapply 但无法从那个例子中弄清楚。 感谢您的帮助。

【问题讨论】:

    标签: r list dataframe match sapply


    【解决方案1】:

    有几种方法可以做到这一点。基本 R 中与您已有的方法接近的一种方法是 which() 结合 %in%

    Gene <- c("123", "327", "445", "557", "789", "123", "557")
    Taxa <- c("A", "B", "D", "A", "E", "B", "C")
    toDrop <- data.frame(Gene, Taxa)
    Temp <- list()
    geneNameTemp <- "123"
    Temp <- as.list(toDrop[which(toDrop$Gene %in% geneNameTemp),2])
    Temp
    # [[1]]
    # [1] A
    # Levels: A B C D E
    # 
    # [[2]]
    # [1] B
    # Levels: A B C D E
    

    将返回一个包含两个因素的列表。此方法可以扩展为向量geneNameTemp,但如果有重复,它将包括重复

    Gene <- c("123", "327", "445", "557", "789", "123", "557")
    Taxa <- c("A", "B", "D", "A", "E", "B", "C")
    toDrop <- data.frame(Gene, Taxa)
    Temp <- list()
    geneNameTemp <- c("123", "327")
    Temp <- as.list(toDrop[which(toDrop$Gene %in% geneNameTemp),2])
    Temp
    # [[1]]
    # [1] A
    # Levels: A B C D E
    # 
    # [[2]]
    # [1] B
    # Levels: A B C D E
    # 
    # [[3]]
    # [1] B
    # Levels: A B C D E
    

    如果您只需要一个带有因子的向量,您可以删除as.list()。如果要删除重复项,可以使用unique(toDrop[which(toDrop$Gene %in% geneNameTemp),2])

    【讨论】:

    • 太棒了!这就是我一直在寻找的。一个编辑虽然它应该是toDrop[which(toDrop$Gene %in% geneNameTemp),2] 你需要在基因之前的数据框。非常感谢。
    【解决方案2】:
    Gene <- c("123", "327", "445", "557", "789", "123", "557")
    Taxa <- c("A", "B", "D", "A", "E", "B", "C")
    toDrop <- data.frame(Gene, Taxa, stringsAsFactors = FALSE)
    

    有很多方法可以做到这一点。使用data.table,可以很容易地按值拆分列并返回一个列表。由于您只对Taxa 列感兴趣,您可以执行以下操作:

    library(data.table)
    lapply(
      split(setDT(toDrop), by = "Gene"), function(d) d[['Taxa']]
    )
    
    $`123`
    [1] "A" "B"
    
    $`327`
    [1] "B"
    
    $`445`
    [1] "D"
    
    $`557`
    [1] "A" "C"
    
    $`789`
    [1] "E"
    

    【讨论】:

    • 好的,但我仍然很困惑如何使用我的示例中的geneNameTemp 在循环中使用您的答案?
    • 我不知道,因为你没有给出一个可重复的例子来说明你想做什么。之后制作一个子集不够精确,无法为您提供帮助。另一个数据框的结构是什么?
    • 下游不应该适用于所写的问题。鉴于我提供的数据框(toDrop),我如何使用geneNameTemp 来匹配 toDrop$Gene 获取“A”和“B”的列表?不只是第一次使用 match?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 2022-08-12
    相关资源
    最近更新 更多