Je dois filtrer un cadre de données en utilisant comme critère les lignes contenant la chaîne RTB
. J'utilise dplyr
.
d.del <- df %.%
group_by(TrackingPixel) %.%
summarise(MonthDelivery = as.integer(sum(Revenue))) %.%
arrange(desc(MonthDelivery))
Je sais que je peux utiliser la fonction filter
dans dplyr
mais je ne sais pas exactement comment lui dire de vérifier le contenu d'une chaîne.
En particulier, je souhaite vérifier le contenu de la colonne TrackingPixel
. Si la chaîne contient le libellé RTB
, je souhaite supprimer la ligne du résultat.
La réponse à la question avait déjà été postée par le @latemail dans les commentaires ci-dessus. Vous pouvez utiliser des expressions régulières pour le deuxième argument et les arguments suivants de filter
comme ceci:
dplyr::filter(df, !grepl("RTB",TrackingPixel))
Puisque vous n'avez pas fourni les données d'origine, je vais ajouter un exemple de jouet en utilisant l'ensemble de données mtcars
. Imaginez que vous ne soyez intéressé que par les voitures produites par Mazda ou Toyota.
mtcars$type <- rownames(mtcars)
dplyr::filter(mtcars, grepl('Toyota|Mazda', type))
mpg cyl disp hp drat wt qsec vs am gear carb type
1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 Mazda RX4
2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 Mazda RX4 Wag
3 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 Toyota Corolla
4 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1 Toyota Corona
Si vous souhaitez utiliser la méthode inverse, à savoir l'exclusion des voitures Toyota et Mazda, la commande filter
ressemble à ceci:
dplyr::filter(mtcars, !grepl('Toyota|Mazda', type))
Solution
Il est possible d'utiliser str_detect
du package stringr
inclus dans le package tidyverse
. str_detect
renvoie True
ou False
indiquant si le vecteur spécifié contient une chaîne spécifique. Il est possible de filtrer en utilisant cette valeur booléenne. Voir Introduction à stringr pour plus de détails sur le paquet stringr
.
library(tidyverse)
# ─ Attaching packages ──────────────────── tidyverse 1.2.1 ─
# ✔ ggplot2 2.2.1 ✔ purrr 0.2.4
# ✔ tibble 1.4.2 ✔ dplyr 0.7.4
# ✔ tidyr 0.7.2 ✔ stringr 1.2.0
# ✔ readr 1.1.1 ✔ forcats 0.3.0
# ─ Conflicts ───────────────────── tidyverse_conflicts() ─
# ✖ dplyr::filter() masks stats::filter()
# ✖ dplyr::lag() masks stats::lag()
mtcars$type <- rownames(mtcars)
mtcars %>%
filter(str_detect(type, 'Toyota|Mazda'))
# mpg cyl disp hp drat wt qsec vs am gear carb type
# 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 Mazda RX4
# 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 Mazda RX4 Wag
# 3 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 Toyota Corolla
# 4 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1 Toyota Corona
Les avantages de Stringr
Nous devrions utiliser plutôt stringr::str_detect()
que base::grepl()
. C'est parce qu'il y a les raisons suivantes.
stringr
commencent par le préfixe str_
, ce qui facilite la lecture du code.stringr
est toujours le data.frame (ou la valeur), puis viennent les paramètres. (Merci Paolo)object <- "stringr"
# The functions with the same prefix `str_`.
# The first argument is an object.
stringr::str_count(object) # -> 7
stringr::str_sub(object, 1, 3) # -> "str"
stringr::str_detect(object, "str") # -> TRUE
stringr::str_replace(object, "str", "") # -> "ingr"
# The function names without common points.
# The position of the argument of the object also does not match.
base::nchar(object) # -> 7
base::substr(object, 1, 3) # -> "str"
base::grepl("str", object) # -> TRUE
base::sub("str", "", object) # -> "ingr"
Référence
Les résultats du test de référence sont les suivants. str_detect
est plus rapide pour les grandes trames de données.
library(rbenchmark)
library(tidyverse)
# The data. Data expo 09. ASA Statistics Computing and Graphics
# http://stat-computing.org/dataexpo/2009/the-data.html
df <- read_csv("Downloads/2008.csv")
print(dim(df))
# [1] 7009728 29
benchmark(
"str_detect" = {df %>% filter(str_detect(Dest, 'MCO|BWI'))},
"grepl" = {df %>% filter(grepl('MCO|BWI', Dest))},
replications = 10,
columns = c("test", "replications", "elapsed", "relative", "user.self", "sys.self"))
# test replications elapsed relative user.self sys.self
# 2 grepl 10 16.480 1.513 16.195 0.248
# 1 str_detect 10 10.891 1.000 9.594 1.281
Cette réponse ressemble à d’autres, mais utilise les stringr::str_detect
et dplyr rownames_to_column
préférés.
library(tidyverse)
mtcars %>%
rownames_to_column("type") %>%
filter(stringr::str_detect(type, 'Toyota|Mazda') )
#> type mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
#> 2 Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
#> 3 Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
#> 4 Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
Créé le 2018-06-26 par le paquet reprex (v0.2.0).
Si vous voulez trouver la chaîne dans toute colonne donnée, regardez
Supprimer la ligne si une colonne contient une chaîne spécifique
Il s’agit essentiellement d’utiliser filter_at
ou filter_all