【问题标题】:Subset dataframe to contain only cells that match a pattern in r子集数据框以仅包含与 r 中的模式匹配的单元格
【发布时间】:2018-01-09 07:00:41
【问题描述】:

我是 R 的初学者,这是一个非常简单的问题,但我找不到答案。

我想在表格中选择与特定模式匹配的单元格并排除其他所有内容。

示例数据:

data.t <- data.frame(ColA = c("NARG_ECOLI^Q:103", "NARG_ECOLI^NARG", "SPEB_KLEP7^Q:103"), ColB = c(NA, NA, NA), ColC = c("KLEP7^Q:103", "NARG_ECOLI^KLEP7", NA), ColD = c("RPOC_ENTFA^Q:2", NA, NA), ColE = c("Y1546_STAS1^Q:6", NA, NA))

生成这样的表:

              ColA ColB             ColC           ColD ColE
1 NARG_ECOLI^Q:103   NA      KLEP7^Q:103 RPOC_ENTFA^Q:2   NA
2  NARG_ECOLI^NARG   NA NARG_ECOLI^KLEP7           <NA>   NA
3 SPEB_KLEP7^Q:103   NA             <NA>           <NA>   NA

我想只选择包含 ECOLI 的单元格。因此,所需的输出将如下所示:

              ColA             ColC
1 NARG_ECOLI^Q:103 NARG_ECOLI^KLEP7
2  NARG_ECOLI^NARG             <NA>

一种可能的解决方案是目视检查并在我的数据中进行选择,但实际的表有几十列和几百行。任何帮助将不胜感激。提前谢谢!

【问题讨论】:

    标签: r filtering subset


    【解决方案1】:

    如果您只想返回数据框中包含“ECOLI”的项目,那么这里是tidyverse 方法

    library(tidyverse)
    
    filter_all(data.t, any_vars(grepl("ECOLI", .))) %>% 
     .[map_lgl(.,  ~any(grepl("ECOLI", .x)))] %>% 
      map_df(~replace(.x, !grepl("ECOLI", .x), NA_character_))
    
       # A tibble: 2 x 2
                  ColA             ColC
                <fctr>           <fctr>
    1 NARG_ECOLI^Q:103             <NA>
    2  NARG_ECOLI^NARG NARG_ECOLI^KLEP7
    

    【讨论】:

    • @PedroDaPos IMO,解决方案有效。结果中显示的值是预期值。似乎示例在 OP 中是错误的
    【解决方案2】:
    data.t <- data.t[grepl('ECOLI', data.t$ColA), ]
    

    获取data.t每一列中所有ECOLI实例的交错列表:

    out <- lapply(data.t, grep, pattern='ECOLI', value=T)
    

    如果你想删除 0 长度的条目。

    nout <- sapply(out, length)
    out <- out[nout > 0]
    nout <- nout[nout > 0]
    

    将交错的列表合并成一个像数据框一样的矩形对象是不明智的,但是:

    mapply(c, out, mapply(rep, NA, max(nout)-nout))
    

    【讨论】:

    • 谢谢你,AdamO。这适用于玩具数据,您可以在其中轻松找到 ECOLI 单元格。不幸的是,我需要一些可以为更大的表自动执行子集设置的方法,并且我只需要包含 ECOLI 的单元格就可以在输出中。
    • @PedroDaPos 我已经编辑了我的问题,因为我相信我错过了您的原始规格。我认为我之前的答案甚至不适用于您的玩具数据。
    【解决方案3】:

    我尝试使用base 函数解决这个问题。

    # Data
    data.t <- data.frame(ColA = c("NARG_ECOLI^Q:103", "NARG_ECOLI^NARG",
    "SPEB_KLEP7^Q:103"), ColB = c(NA, NA, NA), ColC = c("KLEP7^Q:103", 
    "NARG_ECOLI^KLEP7", NA), ColD = c("RPOC_ENTFA^Q:2", NA, NA), ColE = 
    c("Y1546_STAS1^Q:6", NA, NA), stringsAsFactors = FALSE)
    
    # First wrote a function to check cell value. If value contains
     "ECOLI" then value # of cell is retained else value is replaced with NA
    findECOLI <- function(x){
        ifelse(grepl("ECOLI", x, fixed = TRUE), x, NA)
    }
    
    d1 <- sapply(data.t,  findECOLI)
    
    #> d1
    #     ColA               ColB ColC               ColD ColE
    #[1,] "NARG_ECOLI^Q:103" NA   NA                 NA   NA  
    #[2,] "NARG_ECOLI^NARG"  NA   "NARG_ECOLI^KLEP7" NA   NA  
    #[3,] NA                 NA   NA                 NA   NA 
    
    # Now, remove the rows containing only NA
    d1 <- d1[rowSums(is.na(d1)) != ncol(d1), ]
    #> d1
    #     ColA               ColB ColC               ColD ColE
    #[1,] "NARG_ECOLI^Q:103" NA   NA                 NA   NA  
    #[2,] "NARG_ECOLI^NARG"  NA   "NARG_ECOLI^KLEP7" NA   NA
    
    # Remove the columns containing only NA
    d1 <- d1[, colSums(is.na(d1)) != nrow(d1)]
    
    #Result:
    #>d1
    #     ColA               ColC              
    #[1,] "NARG_ECOLI^Q:103" NA                
    #[2,] "NARG_ECOLI^NARG"  "NARG_ECOLI^KLEP7"
    

    【讨论】:

      猜你喜欢
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 2017-12-15
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 2023-04-06
      相关资源
      最近更新 更多