Фильтр, если функция возвращает FALSE - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть фрейм данных, который содержит столбец с разделенным запятыми списком слов:

   df <- data.frame(gene=c("1", "2", "3", "4"), affected_genes = c("Rim2, CG18208", "ANB, XYZ", "Gene1, Gene2", "XYZ"))

 gene affected_genes
    1  Rim2, CG18208
    2       ANB, XYZ
    3   Gene1, Gene2
    4            XYZ

Я хочу отфильтровать строки, в которых affected_genes не содержит XYZ. Вот что я пытаюсь:

library(dplyr)

geneIn <- function(gene, gene_list){
    gene %in% sapply(gene_list, function(x) strsplit(x, ", ")[[1]], USE.NAMES=FALSE)
  }


df %>%
    dplyr::filter(geneIn("XYZ", affected_genes))

Однако это не с Error in filter_impl(.data, quo) : Evaluation error: non-character argument.

Когда я бегу:

affected_genes <- "ANB, XYZ"
geneIn("XYZ", affected_genes)

Я получил ожидаемый результат (TRUE). Кто-нибудь может подсказать, что я делаю неправильно в моем первом примере?

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Две вещи: ваш df$affected_genes представляется фактором, поэтому либо превратите их в класс char (например, включив stringsAsFactors=FALSE в ваш вызов read.table), либо сначала пропустите столбец через as.character. Во-вторых, вы хотите вставить свой %in% в sapply, потому что в противном случае вы получите вектор длины 1 в качестве ответа (он проверит, присутствует ли ген где-нибудь в списке всех отдельных имен генов) вместо ИСТИНА / ЛОЖЬ для каждой строки. В целом код вашей функции должен быть:

geneIn <- function(gene, gene_list) {
            sapply(as.character(gene_list), function(x) gene %in% strsplit(x, ", ")[[1]], USE.NAMES=FALSE)
          }

Что хорошо работает:

df %>% dplyr::filter(geneIn("XYZ", affected_genes))

  gene affected_genes
1    2       ANB, XYZ
2    4            XYZ
0 голосов
/ 15 ноября 2018

Вы не должны иметь несколько генов в одной строке символов.Концепция «аккуратных данных», определенная Хэдли Уикхемом, требует следующий формат:

gene affected_gene
   1          Rim2
   1       CG18208
   2           ANB
   2           XYZ
      ...

Однако вам следует как минимум разбить строки символов и создать столбец списка, если вы хотите дополнительно проанализировать эти данные:

df$affected_genes <-  lapply(strsplit(as.character(df$affected_genes), ","), trimws)
df[vapply(df$affected_genes, `%in%`, x = "XYZ", FUN.VALUE = logical(1)),]
#  gene affected_genes
#2    2       ANB, XYZ
#4    4            XYZ

С приведенным выше форматом аккуратности вам не понадобится цикл *apply.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...