【问题标题】:Subsetting a Data Frame Based on Character Ending基于字符结尾的数据帧子集
【发布时间】:2018-09-05 04:13:13
【问题描述】:

我是 R 的新手。我有一个 data.frame。开头和结尾分别是这样的:

我想要做的是根据“条形码”列的最后一位数字对该数据框进行子集化。数字从 1 到 16,所以有 16 个组。我想将这 16 人分成 5 组。例如,所有以“1”和“2”结尾的条形码将成为数据帧的一个子集,所有以“3”、“4”和“5”结尾的条形码将进入另一个子集,依此类推。

我使用which()endsWith() 函数进行了尝试:

my_frame = data.frame()
character_one = as.character(1)
subset_by_group_one <- my_frame[which(endsWith(my_frame, character_one)),]

但是,我收到以下错误:

Error in endsWith(barcode_subset, character_one) : non-character object(s)

似乎基于R documentationendsWith() 函数必须接受一个字符,而不是一个数据框。然而,我想在我的数据框中使用它——或类似的东西——来对其进行子集化。最好的方法是什么?有没有办法将数据框强制转换为字符?我需要使用循环来遍历数据框吗?

【问题讨论】:

  • 1,2 第一个数据帧,3,4,5 第二个数据帧,剩下的呢?锄头你确定? 6,7,8,9,10,11,12,13,14.15,16?您如何将其分解为剩余的 3 个数据框?
  • 请使用例如dputhead以纯文本形式提供数据,而不是图像,以便其他用户可以复制/粘贴。
  • 问题是my_frame 是一个完整的数据框而不是一列。你可能想要endsWith(my_frame$barcode,...)
  • 一般来说,学习一些有关数据帧和子集如何在 R 中工作的基础知识,您会受益匪浅。以下是一些建议阅读:adv-r.had.co.nz/Subsetting.html 请不要发布图片您的数据或代码。
  • @Dan Hall,抱歉粘贴图片并感谢您提供链接。我希望明天有时间通读它和下面的 cmets。

标签: r regex dataframe subset


【解决方案1】:

您想根据正则表达式模式对行进行子集化(以“16”结尾,即"16$"。我认为最直接的方法是使用逻辑向量,该逻辑向量对于那些结束的行是正确的在 16. 使用grepl(pattern, x) 生成逻辑向量,其中x 是包含您感兴趣的值的列。然后通过在子集表达式my_frame[&lt;index vector&gt;,] 的行位置使用该逻辑索引向量根据行进行子集. 看看下面的数据是如何模拟的。drop 设置为 FALSE 以防行名实际上是行名而不是​​另一列(并且您没有另一列)。

my_frame[grepl("16$", my_frame$barcode),, drop = FALSE]
#                               barcode other
# GACCTAAATGCCTGT-16 GACCTAAATGCCTGT-16  blah
# GAAATTGACATGACT-16 GAAATTGACATGACT-16  blah

数据:

barcode <- replicate(32, {
  paste(sample(c("T", "A", "C", "G"), 15, replace = TRUE), collapse = "")
})
barcode <- paste0(barcode, "-", 1:16)
my_frame <- data.frame(row.names = barcode, barcode = barcode, other = rep("blah", 32), stringsAsFactors = FALSE)
head(my_frame)
#                             barcode other
# GTCCGGTGATGATAA-1 GTCCGGTGATGATAA-1  blah
# CTGCTACATATAGAA-2 CTGCTACATATAGAA-2  blah
# GTGACCGTGGTCGAA-3 GTGACCGTGGTCGAA-3  blah
# TCTAGGACGATTACT-4 TCTAGGACGATTACT-4  blah
# GAGGGAGGCGTCCAT-5 GAGGGAGGCGTCCAT-5  blah
# CAGCAGCCTCCACCG-6 CAGCAGCCTCCACCG-6  blah

【讨论】:

    【解决方案2】:

    我正在使用 Dan Hall 的示例。这通过删除包括破折号在内的所有材料来构建“拆分/分组向量”,将其转换为数字,然后使用 findInterval 进行分组。分组有点不清楚,但您可以修改 findInterval 的第二个参数来调整:

     grp <- findInterval( as.numeric( gsub("^.+[-]", "", my_frame$barcode)), 
                           c(.5, 2.5, 5.5, 8.5, 12.5, 16.5)) #split boundaries
    > split( my_frame, grp)
    $`1`
                                barcode other
    TCGCGCGTTACATGT-1 TCGCGCGTTACATGT-1  blah
    GCGTGTTATCCGCCT-2 GCGTGTTATCCGCCT-2  blah
    CTCCCTCTTCTGTGC-1 CTCCCTCTTCTGTGC-1  blah
    TTCTTGTGCGACAAA-2 TTCTTGTGCGACAAA-2  blah
    
    $`2`
                                barcode other
    CTTACGTCGTCAGCA-3 CTTACGTCGTCAGCA-3  blah
    CCCATGTGTGACTAC-4 CCCATGTGTGACTAC-4  blah
    GAGCCCAGAACTGTG-5 GAGCCCAGAACTGTG-5  blah
    GTTGGCGAGCAGCAT-3 GTTGGCGAGCAGCAT-3  blah
    ATTTAGGGGACCCAA-4 ATTTAGGGGACCCAA-4  blah
    TGGCCAATGCGTTGA-5 TGGCCAATGCGTTGA-5  blah
    
    $`3`
                                barcode other
    TCCGTCCGGGGAGGA-6 TCCGTCCGGGGAGGA-6  blah
    TTCAAATCGTCTACT-7 TTCAAATCGTCTACT-7  blah
    AGGTACAATCTCGCA-8 AGGTACAATCTCGCA-8  blah
    CGTGACTCCAATGGT-6 CGTGACTCCAATGGT-6  blah
    CCGGGGGGTTGCCCC-7 CCGGGGGGTTGCCCC-7  blah
    CTTTAAGTGTGTCAG-8 CTTTAAGTGTGTCAG-8  blah
    
    $`4`
                                  barcode other
    TGCTGACAGTTAGAG-9   TGCTGACAGTTAGAG-9  blah
    GGAAGGTGCAGAGGC-10 GGAAGGTGCAGAGGC-10  blah
    AATTTAGGGCGGCCT-11 AATTTAGGGCGGCCT-11  blah
    CCATCATGCGGGACG-12 CCATCATGCGGGACG-12  blah
    TCCGAATCTGAGCAA-9   TCCGAATCTGAGCAA-9  blah
    TCCCACCCTTTCTCG-10 TCCCACCCTTTCTCG-10  blah
    CTCCTGGTCGCCACA-11 CTCCTGGTCGCCACA-11  blah
    TCCCGCAACATGTAC-12 TCCCGCAACATGTAC-12  blah
    
    $`5`
                                  barcode other
    TAAGAGTGCCAGTCC-13 TAAGAGTGCCAGTCC-13  blah
    ACTCCACTGCCCAAC-14 ACTCCACTGCCCAAC-14  blah
    CACCGTGGGTGCACA-15 CACCGTGGGTGCACA-15  blah
    TGGGTGTCTGTCATG-16 TGGGTGTCTGTCATG-16  blah
    CTGACATTGGTACAC-13 CTGACATTGGTACAC-13  blah
    GCGCAGGTTCGAACC-14 GCGCAGGTTCGAACC-14  blah
    TTTTTTCCCCCGACC-15 TTTTTTCCCCCGACC-15  blah
    CCCAGCTGCCATTGA-16 CCCAGCTGCCATTGA-16  blah
    

    【讨论】:

      【解决方案3】:

      其实你要找的函数是base::endsWith。它返回一个布尔向量,并将变量作为第一个参数。

      df2 <- df1[endsWith(df1$z,"2"),]
      #    z whatev
      # 1 x2   blah
      # 3 l2   blah
      # 4 y2   blah
      # 5 o2   blah
      # 8 v2   blah
      

      dplyr::ends_with 本质上是在dplyr 调用中使用的,尤其是 select,尽管我们可以通过注意参数顺序来使其正常工作。它返回数值,但在这种情况下它没有任何区别。

      library(dplyr)    
      df2 <- df1[ends_with("2",vars=df1$z),]
      #     z whatev
      # 1  v2   blah
      # 3  s2   blah
      # 8  j2   blah
      # 9  n2   blah
      # 10 z2   blah
      

      数据

      set.seed(1)
      df1 <- data.frame(z = paste0(sample(letters,10),sample(1:3,10,T)),whatev="blah",stringsAsFactors=F)
      #     z whatev
      # 1  v2   blah
      # 2  q3   blah
      # 3  s2   blah
      # 4  m1   blah
      # 5  l1   blah
      # 6  y1   blah
      # 7  a1   blah
      # 8  j2   blah
      # 9  n2   blah
      # 10 z2   blah
      

      讽刺的是base::endsWithdplyr::ends_with 更适合dplyr::filter 呼叫。

      【讨论】:

      • 这并不是真正的 dplyr 方法。查看帮助文件中的源代码和使用示例,您会看到编写dplyr::ends_with 是为了查找名称以模式结尾的列。您可以通过将其与基本子集组合来强制它查找行,但我认为使用grepl 更直接。不过它确实有效,所以请点赞!
      • 好吧,参数 vars 的存在是有原因的 :),我想我会向 OP 展示如何让 endswith 在这种情况下工作。但是,是的,这有点尴尬。
      【解决方案4】:

      我会使用正则表达式来提取结尾,然后加入包含组信息的数据框。

      一些示例数据:

      library(tidyverse)
      df1 <- data.frame(x = paste0("AAA-", 1:16))
      

      一些示例组:1-2 = 1; 3-5 = 2; 6-9 = 3; 10-14 = 4; 15-16 = 5。

      加入df1:

      df1 %>% 
        mutate(suffix = str_match(x, "-(\\d+)$")[, 2] %>% as.numeric()) %>%
        left_join(data.frame(suffix = 1:16, 
                             group = c(1,1,2,2,2,3,3,3,3,4,4,4,4,4,5,5)))
      
              x suffix group
      1   AAA-1      1     1
      2   AAA-2      2     1
      3   AAA-3      3     2
      4   AAA-4      4     2
      5   AAA-5      5     2
      6   AAA-6      6     3
      7   AAA-7      7     3
      8   AAA-8      8     3
      9   AAA-9      9     3
      10 AAA-10     10     4
      11 AAA-11     11     4
      12 AAA-12     12     4
      13 AAA-13     13     4
      14 AAA-14     14     4
      15 AAA-15     15     5
      16 AAA-16     16     5
      

      【讨论】:

        猜你喜欢
        • 2016-04-30
        • 2019-09-02
        • 2018-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-17
        相关资源
        最近更新 更多