#r
#r
Вопрос:
У меня следующая проблема:
У меня есть большой фрейм данных, для которого я хотел бы удалить каждую строку, соответствующую этому условию: если значение (строка) внутри столбца содержит символ «:», а следующая строка также содержит символ «:», это приведет к удалению первого.
Что-то вроде этого:
a <- c("value1","value2","value2:a","value2:b","value3")
b <- c(1,2,3,4,5)
df1 <- data.frame(b,a)
b a
1 1 value1
2 2 value2
3 3 value2:a
4 4 value2:b
5 5 value3
к этому, где удаляется только строка, содержащая имя «value2: a», поскольку за ней следует строка, содержащая регулярное выражение «:»
a b
value1 1
value2 2
value2:b 4
value3 5
Заранее большое вам спасибо, я пробовал некоторые решения с циклами for и функцией grepl, но, похоже, это не работает.
Комментарии:
1. хороший вопрос, но вы намеревались, чтобы
a
вектор был вектором имен строк или столбцом?2. только значения внутри столбца, извините!
Ответ №1:
Для этого вам не нужны циклы. Вы можете сделать это с одной строкой в базе R, объединив a grepl
с запаздывающим grepl
df1[!c(head(grepl(":", df1$a), -1) amp; tail(grepl(":", df1$a), -1), FALSE),]
#> b a
#> 1 1 value1
#> 2 2 value2
#> 4 4 value2:b
#> 5 5 value3
Комментарии:
1.
setDT(df1)[!c(head(grepl(":", a), -1) amp; tail(grepl(":", a), -1), FALSE)]
этоdata.table
решение. (OP говорит, что его данные большие)
Ответ №2:
Вот dplyr
решение.
library(dplyr)
df1 %>%
mutate(flag = grepl(":", a),
flag = cumsum(flag)*flag,
flag = lead(flag, default = 0)) %>%
filter(flag != 2) %>%
dplyr::select(-flag)
# b a
#1 1 value1
#2 2 value2
#3 4 value2:b
#4 5 value3
Ответ №3:
Попробуйте это:
df1 %>%
dplyr::filter(
!(stringr::str_detect(a, ":") amp; stringr::str_detect(lead(a), ":"))
)
Ответ №4:
Вот так. Для подобных задач мне всегда нравится использовать пару масок.
a <- c("value1","value2","value2:a","value2:b","value3")
b <- c(1,2,3,4,5)
df1 <- as.data.frame(b,a)
stringr::str_extract(pattern = ":",string = rownames(df1)) -> vec
mask_colon = duplicated(vec,fromLast = FALSE)
mask_na = is.na(vec)
df1 = df1[which(mask_na | mask_colon),, drop = FALSE]
df1
#> b
#> value1 1
#> value2 2
#> value2:b 4
#> value3 5
Создано 2020-10-07 пакетом reprex (версия 0.3.0)