Фильтрация данных по наличию выборки в отдельном списке - PullRequest
2 голосов
/ 27 октября 2019

Я хочу отфильтровать фрейм данных с 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

list = 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" ...

1 Ответ

0 голосов
/ 29 октября 2019

AFAIK R не предлагает удобную функцию для поиска вектора строк поиска в векторе строк, используя частичное соответствие («подстроки»).

%in - неправильная функция, если выЯ хочу найти подстроку в строке, поскольку она сравнивает только целые строки.

Вместо этого используйте базовые R * grepl или, возможно, более быструю stri_detect_fixed функцию превосходного пакета stringi.

Обратите внимание, что для упрощения понимания я абстрагировал код и данные (вместо того, чтобы использовать ваш код и данные).

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...