it-swarm.com.de

Zeile filtern, die eine bestimmte Zeichenfolge enthält, mithilfe von dplyr

Ich muss einen Datenrahmen anhand der Zeile filtern, in der der String RTB..__ enthalten ist. Ich verwende dplyr.

d.del <- df %.%
  group_by(TrackingPixel) %.%
  summarise(MonthDelivery = as.integer(sum(Revenue))) %.%
  arrange(desc(MonthDelivery))

Ich weiß, dass ich die Funktion filter in dplyr verwenden kann, aber ich kann nicht genau sagen, wie ich sie auf den Inhalt eines Strings überprüfen soll.

Insbesondere möchte ich den Inhalt in der Spalte TrackingPixel überprüfen. Wenn die Zeichenfolge die Beschriftung RTB enthält, möchte ich die Zeile aus dem Ergebnis entfernen.

120
Gianluca

Die Antwort auf die Frage wurde bereits von @latemail in den obigen Kommentaren gepostet. Sie können reguläre Ausdrücke für das zweite und nachfolgende Argument von filter wie folgt verwenden:

dplyr::filter(df, !grepl("RTB",TrackingPixel))

Da Sie die Originaldaten nicht angegeben haben, füge ich ein Spielzeugbeispiel mit dem Datensatz mtcars hinzu. Stellen Sie sich vor, Sie interessieren sich nur für Autos von Mazda oder 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

Wenn Sie es umgekehrt machen möchten, nämlich ohne Toyota und Mazda, sieht der Befehl filter folgendermaßen aus:

dplyr::filter(mtcars, !grepl('Toyota|Mazda', type))
180
alex23lemm

Lösung

Es ist möglich, str_detect des stringr-Pakets zu verwenden, das im tidyverse-Paket enthalten ist. str_detect gibt True oder False zurück, ob der angegebene Vektor eine bestimmte Zeichenfolge enthält. Mit diesem booleschen Wert kann gefiltert werden. Siehe Einführung in stringr für Details zum stringr-Paket.

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

Die guten Dinge über Stringr

Wir sollten eher stringr::str_detect() als base::grepl() verwenden. Dies liegt daran, dass es folgende Gründe gibt.

  • Die vom Paket stringr bereitgestellten Funktionen beginnen mit dem Präfix str_, wodurch der Code leichter lesbar wird.
  • Das erste Argument der Funktionen von stringr ist immer der data.frame (oder value), dann die Parameter. (Vielen Dank, 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"

Benchmark

Die Ergebnisse des Benchmark-Tests sind wie folgt. Bei großen Datenrahmen ist str_detect schneller.

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
87
Keiku

Diese Antwort ähnelt anderen, verwendet jedoch bevorzugt stringr::str_detect und dplyr rownames_to_column.

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

Erstellt am 2018-06-26 durch das Paket reprex (v0.2.0).

5
Nettle

Wenn Sie den String in einer beliebigen Spalte finden möchten, schauen Sie sich das an 

Zeile entfernen, wenn eine Spalte eine bestimmte Zeichenfolge enthält

Grundsätzlich geht es um filter_at oder filter_all

0
Tjebo