Как извлечь определенные строки из набора данных на основе условия word

#r

Вопрос:

У меня есть этот образец набора данных

 df=structure(list(V1 = c("", "", "", ""), V2 = c("Segunda", "VACUNA SinoVac", 
"Primera", "PARTICULAR"), V3 = c("Dosis por aplicar", "UNIDAD DE SERVICIOS DE", 
"Aplicada", ""), V4 = c(NA, NA, "16", "SALUD CALLE 153"), V5 = c(NA, 
NA, "7", NA), V6 = c(NA, NA, "2021 202105061K No registra", NA
), V7 = c(NA, NA, "6", NA), V8 = c(NA, NA, "8", NA), V9 = c(NA, 
NA, "2021", NA), V10 = c(NA, NA, "ADRIANA JAIME", NA), V11 = c(NA_character_, 
NA_character_, NA_character_, NA_character_), V12 = c(NA_character_, 
NA_character_, NA_character_, NA_character_)), row.names = 53:56, class = "data.frame")
 

В настоящее время я извлекаю строку (назовем ее строкой X), содержащую слово «Aplicada».

 df.out1 = df %>% filter_all(any_vars(. %in% c("Aplicada")))
 

Но теперь мне также требуется извлечь всю строку перед строкой X, чтобы получить желаемый результат:

 structure(list(V1 = c("", ""), V2 = c("VACUNA SinoVac", "Primera"
), V3 = c("UNIDAD DE SERVICIOS DE", "Aplicada"), V4 = c(NA, "16"
), V5 = c(NA, "7"), V6 = c(NA, "2021 202105061K No registra"), 
    V7 = c(NA, "6"), V8 = c(NA, "8"), V9 = c(NA, "2021"), V10 = c(NA, 
    "ADRIANA JAIME"), V11 = c(NA_character_, NA_character_), 
    V12 = c(NA_character_, NA_character_)), row.names = 54:55, class = "data.frame")
 

Не могли бы вы дать мне совет?

Ответ №1:

Не удастся, если совпадение найдено в первой строке:

 dplyr::slice(
  dat, 
  sapply(which(rowSums(dat == 'Aplicada', TRUE) == 1), (x) { (x - 1):x }) 
)

#   V1             V2                     V3   V4   V5  <truncated>
# 1    VACUNA SinoVac UNIDAD DE SERVICIOS DE <NA> <NA>  <truncated>
# 2           Primera               Aplicada   16 7 202 <truncated>
 

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

1. спасибо за совет. постараюсь. к счастью, матч в первом ряду не будет проблемой, афаик

2. Это версия R. Анонимная функция (x) { ... } введена только в R 4.1. Изменение function(x) (x - 1):x должно работать.

Ответ №2:

Я написал код, который должен работать так, как Вы хотите.

 y <- nrow(df)

for(i in 1:nrow(df)) {
  y[i] <- any(df[i, ] %in% c("Aplicada"))
  if(i > 1 amp; y[i] == 1) {
    y[i - 1] <- 1
  }
}

df[as.logical(y), ]
 

Я попытался использовать функцию apply вместо цикла, но она работала неправильно.

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

1. Вместо y <- nrow(df) тебя мог бы пригодиться y <- logical(0) . В этом случае замените y[i] == 1 на просто y[i] и назначьте y[i - 1] <- TRUE . А теперь тебе только нужно df[y,] . 😉 И вы могли бы заменить 1:nrow(df) на seq_len(nrow(df)) . Если df пусто, это предотвращает for выполнение цикла-loopf.

Ответ №3:

Опрятный вариант.

 library(dplyr)
library(stringr)

keep <- df %>%
  mutate(id = row_number()) %>%
  filter(if_any(everything(), ~ str_detect(., 'Aplicada'))) %>%
  pull(id)

df %>%
  slice((keep-1):keep)
  
#   V1             V2                     V3   V4   V5                          V6   V7   V8   V9
# 1    VACUNA SinoVac UNIDAD DE SERVICIOS DE <NA> <NA>                        <NA> <NA> <NA> <NA>
# 2           Primera               Aplicada   16    7 2021 202105061K No registra    6    8 2021
#             V10  V11  V12
# 1          <NA> <NA> <NA>
# 2 ADRIANA JAIME <NA> <NA>