Удалите строки, если строка соответствует X, но не Y

#r #string #filter #subset

#r #строка #Фильтр #подмножество

Вопрос:

У меня есть следующий фрейм данных:

 data <- data.frame(id = c(1,2,3,4,5,6),
                   exposure = c("BMI", "BMI etc.", "BMI neuronal", "WHRadjBMI", "WHR", "BF"))
 
     
    id  exposure
1   1   BMI
2   2   BMI etc.
3   3   BMI neuronal
4   4   WHRadjBMI
5   5   WHR
6   6   BF
 

Я хочу удалить все строки из этого фрейма данных, которые имеют «BMI», но не «adj» в exposure столбце, чтобы я мог сгруппировать все строки, связанные с BMI, в единый факторный уровень, называемый «BMI. Реальный фрейм данных составляет ~ 2500 строк по 50 столбцов.

Таким образом, подмножество приведет к следующему фрейму данных, здесь строки 1, 2 и 3 были удалены, поскольку они содержат «BMI», но не содержат «adj».:

     id  exposure
4   4   WHRadjBMI
5   5   WHR
6   6   BF
 

Затем я могу объединить «BMI», но не «adj», содержащие строки, в единый факторный уровень, так что строки 1, 2 и 3 станут:

     id  exposure
1   1   BMI
2   2   BMI
3   3   BMI
 

Я могу сделать эту заключительную часть следующим образом:

 data$exposure <- "BMI"
 

Ответ №1:

Мы можем использовать grepl для удаления строк и сведения всех значений экспозиции BMI к одному BMI значению.

 data <- data[!grepl("BMI", data$exposure, fixed=TRUE) ||
             grepl("adj", data$exposure, fixed=TRUE), ]
data$exposure <- ifelse(grepl("BMI", data$exposure, fixed=TRUE),
                        "BMI", data$exposure)
 

Ответ №2:

Использование базового R stringr:

 library(stringr)
data[str_detect(data$exposure, 'BMI') amp; str_detect(data$exposure, 'adj', negate=TRUE),]
 

У вас есть два логических условия в сочетании с логическим И: data$exposure содержит BMI и data$exposure не содержит adj .

Ответ №3:

Я не уверен, что это то, что вы хотите

 within(
  data,
  exposure <- gsub("^(?<=BMI).*", "", exposure, perl = TRUE)
)
 

что дает

   id  exposure
1  1       BMI
2  2       BMI
3  3       BMI
4  4 WHRadjBMI
5  5       WHR
6  6        BF
 

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

1. Это работает именно так, как я хотел (хотя я не совсем уверен, как?). Я думаю, что он просто меняет каждый экземпляр «BMI», за которым следует любая строка символов, на просто «BMI». Таким образом, это ничего не изменит, если «BMI» идет после строки?

2. @мэтт Да, это верно. Замена происходит так, как если бы шаблон соответствовал.

3. Обратите внимание, что это также заменит значение WHRBMIadj на WHRBMI , чего, согласно правилам OP, не должно происходить.

4. @TimBiegeleisen Спасибо за напоминание. Я промахнулся ^ , но теперь исправь это. надеюсь, это решит проблему.

Ответ №4:

Работает ли это?

 library(tidyverse)

filtered_data <- data %>%
  filter(!stringr::str_detect(exposure, "^BMI")) %>%
  mutate(exposure = "BMI")

filtered_data
  id exposure
1  4      BMI
2  5      BMI
3  6      BMI