#r #dataframe #function
Вопрос:
У меня есть фрейм данных:
x1 x2
value 12
john and bob 45
another 87
Я хочу проверить, есть ли строка «боб» среди всех значений. Мне нужна функция, которая будет принимать кадр данных и имя строки и вернет значение TRUE для этого кадра данных. apply(df, 1, function(r) any(r == "bob"))
требуется полное совпадение, поэтому, например, это не работает:
x1 x2
value 12
johnandbob 45
another 87
Также он возвращает TRUEFALSE для каждого значения в кадре данных, поэтому, если у меня миллион значений, будет миллион TRUEFALSE. Однако мне нужен только один, есть ли среди них необходимая ценность или нет. Как это сделать?
Ответ №1:
Используйте grepl
для частичного сопоставления и any
получения только одного значения.
any(grepl('bob', df$x1))
#[1] TRUE
Это также приведет к возврату TRUE
значений , таких как 'bobby'
и 'ambob'
т. Д. Если вы хотите, чтобы он точно соответствовал, используйте границы слов ( \b
) вокруг них.
any(grepl('\bbob\b', df$x1))
Комментарии:
1. спасибо, и прекратит ли он поиск, как только найдет его? или он проверит их всех? у меня есть фрейм данных с десятками миллионов строк и множеством столбцов, поэтому мне нужен алгоритм, который прекратит поиск, как только найдет одно совпадение. в противном случае это займет несколько часов
2. Ну, R-это векторизованный язык. Таким образом, функции, такие как
grepl
работа со всей колонкой сразу. Вы можете написатьfor
цикл, чтобы сделать это один за другим, и остановиться, когда найдете строку, но это будет намного неэффективнее, чем текущий ответ. Если это решение действительно медленное, вам, возможно, потребуется написать цикл,Rcpp
который может ускорить его.
Ответ №2:
Мы могли бы использовать str_detect
из stringr
пакета:
library(dplyr)
library(stringr)
df %>%
mutate(across(everything(), ~str_detect(., "bob")))
Выход:
x1 x2
<lgl> <lgl>
1 FALSE FALSE
2 TRUE FALSE
3 FALSE FALSE
Или для одной колонки a df
any(str_detect(df$x1, "bob"))
Выход:
[1] TRUE
Комментарии:
1. спасибо, и прекратит ли он поиск, как только найдет его? или он проверит их всех? у меня есть фрейм данных с десятками миллионов строк и множеством столбцов, поэтому мне нужен алгоритм, который прекратит поиск, как только найдет одно совпадение. в противном случае это займет несколько часов
2. Попробуйте это
library(stringi) stri_match_first_regex(df1$x1, "bob")