【问题标题】:Filter dataframe based on presence of sample in a seperate list根据单独列表中是否存在样本过滤数据框
【发布时间】:2020-02-23 01:35:19
【问题描述】:

我想用 1212 过滤数据框,因此它只包含单独列表中列出的样本。该列表有多个值,我不知道该怎么做。

下面的df叫做RNASeq2

RNASeq2Norm_samples Substrng_RNASeq2Norm
   1    TCGA-3C-AAAU-01A-11R-A41B-07    TCGA.3C.AAAU
   2    TCGA-3C-AALI-01A-11R-A41B-07    TCGA.3C.AALI
   3    TCGA-3C-AALJ-01A-31R-A41B-07    TCGA.3C.AALJ
   4    TCGA-3C-AALK-01A-11R-A41B-07    TCGA.3C.AALK
   5    TCGA-4H-AAAK-01A-12R-A41B-07    TCGA.4H.AAAK
   6    TCGA-5L-AAT0-01A-12R-A41B-07    TCGA.5L.AAT0
   7    TCGA-5L-AAT1-01A-12R-A41B-07    TCGA.5L.AAT1
   8    TCGA-5T-A9QA-01A-11R-A41B-07    TCGA.5T.A9QA
   .
   .
   .
   1212

列表 = intersect_samples

intersect_samples: "TCGA.3C.AAAU" "TCGA.3C.AALI" "TCGA.3C.AALJ" "TCGA.3C.AALK" ... 1097

我已经尝试过这段代码,但返回了所有原始的 1212 个样本:

RNASeq_filtered <- RNASeq2[RNASeq2$Substrng_RNASeq2Norm %in% intersect_samples,]

如果我尝试

RNASeq_filtered <- RNASeq2[RNASeq2$Substrng_RNASeq2Norm %in% "TCGA.3C.AAAU",]

它将返回正确的行

str(RNASeq2)
'data.frame':   1212 obs. of  2 variables:
 $ RNASeq2             : Factor w/ 1212 levels "TCGA-3C-AAAU-01A-11R-A41B-07",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ Substrng_RNASeq2Norm: Factor w/ 1093 levels "TCGA.3C.AAAU",..: 1 2 3 4 5 6 7 8 9 10 ...
str(intersect_samples)
 chr [1:1093] "TCGA.3C.AAAU" "TCGA.3C.AALI" "TCGA.3C.AALJ" "TCGA.3C.AALK" "TCGA.4H.AAAK" ...

【问题讨论】:

  • 欢迎来到 SO!您能否将str(df)str(intersect_samples) 的输出添加到您的问题中以向我们展示数据类型? THX :-)
  • 恐怕我无法复制这个问题。 RNASeq2[RNASeq2$Substrng_RNASeq2Norm %in% intersect_samples,] 返回预期的子集。
  • match 的第二个参数(%in% 之后的表达式)必须是向量,而不是列表,所以如果你使用列表unlist(intersect_samples) 可能会给你一个向量
  • RYoda 可能正在做点什么。我用intersect_samples &lt;- c("TCGA.3C.AAAU", "TCGA.3C.AALI", "TCGA.3C.AALJ", "TCGA.3C.AALK")
  • RNASeq2[RNASeq2$Substrng_RNASeq2Norm %in% intersect_samples,] 将适用于短列表,但是当intersect_samples 大约为 200 长时,它返回 207 行,当它为 1093 长(即全长)时,它返回 1212,即它不会过滤掉任何东西

标签: r string filter rows string-matching


【解决方案1】:

AFAIK R 不提供使用部分匹配(“子字符串”)在字符串向量中查找搜索字符串向量的便捷功能。

如果您想在字符串中查找子字符串,%in 不是正确的函数,因为它只比较整个字符串。

改为使用基本 R 的 grepl 或出色的 stringi 包中可能更快的 stri_detect_fixed 函数。

请注意,为了便于理解,我已经抽象了代码和数据(而不是使用您的代码和数据)。

library(stringi)

pattern = c("23", "45", "999")
data <- data.frame(row_num = 1:4,
                   string  = c("123", "234", "345", "xyz"),
                   stringsAsFactors = FALSE)
# row_num string
# 1       1    123
# 2       2    234
# 3       3    345
# 4       4    xyz

string <- data$string  # the column that contains the values to be filtered

# Iterate over each element in pattern and apply it to the string vector.
# Returns a logical vector of the same length as string (TRUE = found, FALSE = not found)
selected <- lapply(pattern, function(x) stri_detect_fixed(string, x))
# Or shorter:
# lapply(pattern, stri_detect_fixed, str = string)

selected    # show the result (it is a list of logical vectors - one per search pattern element)
# [[1]]
# [1]  TRUE  TRUE FALSE FALSE
# 
# [[2]]
# [1] FALSE FALSE  TRUE FALSE
# 
# [[3]]
# [1] FALSE FALSE FALSE FALSE

# "row-wise" reduce the logical vectors into one final vector using the logical "or" operator
# WARNING: Does not handle `NA`s correctly (one NA does makes any TRUE to NA)
selected.rows <- Reduce("|", selected)
# [1]  TRUE  TRUE  TRUE FALSE

# To handle NAs correctly (if you have NAs) you can use this (slower) code:
selected.rows <- rowSums(as.data.frame(selected), na.rm = TRUE) > 0

# Use the logical vector as row selector (TRUE returns the row, FALSE ignores the row):
string[selected.rows]
# [1] 123 234 345

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    相关资源
    最近更新 更多