#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>