Проверка соответствия в одном столбце фрейма данных одному из нескольких других столбцов в R

#r

#r

Вопрос:

Допустим, у меня есть df с 4 столбцами. Как я могу добавить столбец, который указывает, соответствует ли строка в столбце 1 строке в любом из столбцов 1-3?

df

     species_A   species_1   species_2   species_3
1   Clostridium breve   Clostridium breve   Eggerthella lenta   Bacillus cereus
2   Splactus blandum Splactus plantarum Splactus pentosus Clostridium adolescentis
3   Rotoroides ovatus   Rotoroides ovatus Pseudomonas oryzihabitans Stenotrophomonas maltophilia
4   Bacillus licheniformis  Phytorotor sp.  Cutirotorium acnes  Rotoroides ovatus
5   Clostridium longum  Clostridium longum  Sphingomonas melonis    Phytorotor sp.
6 Odorirotor splanchnicus   Clostridium longum  Odorirotor splanchnicus Stenotrophomonas maltophilia
  

Я хочу добавить столбец ‘match’ с T / F в зависимости от того, соответствует ли species_A species_1 ИЛИ species_2 ИЛИ species_3:

     species_A   species_1   species_2   species_3   Matches
1   Clostridium breve   Clostridium breve   Eggerthella lenta   Bacillus cereus TRUE
2   Splactus bandum Splactus plantarum  Splactus pentosus Clostridium adolescentis  TRUE
3   Rotoroides ovatus   Rotoroides ovatus Pseudomonas oryzihabitans Stenotrophomonas maltophilia    TRUE
4   Bacillus licheniformis  Phytorotor sp.  Cutirotorium acnes  Rotoroides ovatus   FALSE
5   Clostridium longum  Clostridium longum  Sphingomonas melonis    Phytorotor sp.  TRUE
6 Odorirotor splanchnicus   Clostridium longum  Odorirotor splanchnicus Stenotrophomonas maltophilia    TRUE
  

Основываясь на других потоках, я пытался использовать lapply и sapply, но, похоже, я не могу передать столбец species_A в виде набора шаблонов.

 lapply(df[2:4], function(x) match(x, d$species_A))

sapply(df[2:4],
              function(x) grepl(d$species_A, x, ignore.case = TRUE))
  

Ответ №1:

Попробуйте это:

 rowSums(df$species_A == df[2:4]) > 0
  

Ваши данные трудно импортировать из-за пробелов (используйте dput(df) для совместного использования копируемой / вставляемой версии фрейма данных), поэтому я продемонстрирую некоторые поддельные данные:

 ## copy/pasteable data:
df = data.frame(
  species_A = c("A", "B", "C", "D"),
  species_1 = c("A", "A", "X", "X"),
  species_2 = c("A", "B", "X", "X"),
  species_3 = c("A", "X", "X", "D")
)

df
#   species_A species_1 species_2 species_3
# 1         A         A         A         A
# 2         B         A         B         X
# 3         C         X         X         X
# 4         D         X         X         D


## make comparisons
df$species_A == df[2:4]
#      species_1 species_2 species_3
# [1,]      TRUE      TRUE      TRUE
# [2,]     FALSE      TRUE     FALSE
# [3,]     FALSE     FALSE     FALSE
# [4,]     FALSE     FALSE      TRUE

## see if there are any TRUEs
rowSums(df$species_A == df[2:4]) > 0
# [1]  TRUE  TRUE FALSE  TRUE

## put it together
df$result = rowSums(df$species_A == df[2:4]) > 0

df
#   species_A species_1 species_2 species_3 result
# 1         A         A         A         A   TRUE
# 2         B         A         B         X   TRUE
# 3         C         X         X         X  FALSE
# 4         D         X         X         D   TRUE
  

lapply и sapply это не лучший выбор здесь, потому что они перебирают столбцы 2: 4 и возвращают отдельные результаты для столбцов 2: 4. Мы также могли бы использовать их с rowSums , sapply(df[2:4], "==", df$species_A) это более длинный способ записи df$species_A == df[2:4] .

Комментарии:

1. Оказывается, это не работает в моей установке (R версии 3.6.2). Я получаю следующее, когда запускаю «df $ species_A == df [2: 4]»: Ошибка в df $ species_A == df [2: 4]: сравнение этих типов дополнительно не реализовано: Предупреждающие сообщения: 1: Несовместимые методы («Ops.factor», «Ops.data.frame») для «==» 2: В df $ species_A == df[2:4] : более длинная длина объекта не кратна более короткой длине объекта

2. Ах, похоже, что по крайней мере некоторые из ваших столбцов являются факторами. Преобразуйте их в character векторы. Что-то вроде df[] = lapply(df, as.character) . (R 4.0 переключил значение по умолчанию для фреймов данных с factor на character — изменение, которое ожидалось долгое время.)