문자열이 포함 된 행을 기준으로 사용하여 데이터 프레임을 필터링해야합니다 RTB
.
을 사용하고 dplyr
있습니다.
d.del <- df %.%
group_by(TrackingPixel) %.%
summarise(MonthDelivery = as.integer(sum(Revenue))) %.%
arrange(desc(MonthDelivery))
함수 filter
를 사용할 수 있다는 것을 알고 dplyr
있지만 문자열의 내용을 확인하도록 알려주는 방법을 정확히 알지 못합니다.
특히 열의 내용을 확인하고 싶습니다 TrackingPixel
. 문자열에 레이블이 포함되어 있으면 RTB
결과에서 행을 제거하고 싶습니다.
답변
질문에 대한 답변은 이미 @latemail에 의해 위의 의견에 게시되었습니다. 다음과 filter
같은 두 번째 및 후속 인수에 정규식을 사용할 수 있습니다 .
dplyr::filter(df, !grepl("RTB",TrackingPixel))
원본 데이터를 제공하지 않았으므로 mtcars
데이터 세트 를 사용하여 장난감 예제를 추가합니다 . Mazda 또는 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
Toyota와 Mazda 자동차를 제외하고 다른 방법으로 원한다면 filter
명령은 다음과 같습니다.
dplyr::filter(mtcars, !grepl('Toyota|Mazda', type))
답변
해결책
사용할 수 str_detect
의 stringr
에 포함 패키지 tidyverse
패키지. str_detect
반환 True
또는 False
지정된 벡터 일부 특정 문자열을 포함하는지에. 이 부울 값을 사용하여 필터링 할 수 있습니다. 패키지에 대한 자세한 내용은 스트링거 소개를 참조하십시오 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
Stringr에 대한 좋은 점
우리는 오히려 사용해야합니다 stringr::str_detect()
보다 base::grepl()
. 다음과 같은 이유가 있기 때문입니다.
stringr
패키지에서 제공하는 함수 는 prefixstr_
를 사용하여 코드를보다 쉽게 읽을 수있게합니다.stringr
package 함수의 첫 번째 인수 는 항상 data.frame (또는 value)이며 매개 변수가옵니다. (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"
기준
벤치 마크 테스트 결과는 다음과 같습니다. 큰 데이터 프레임의 경우 str_detect
더 빠릅니다.
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
답변
이것은 다른 것과 비슷하지만 preferred stringr::str_detect
및 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
reprex 패키지 (v0.2.0)로 2018-06-26에 작성되었습니다 .
답변
최신 across()
구문이 포함 된 편집
다음은 또는 previous를 tidyverse
사용하는 다른 솔루션 입니다. 장점은 둘 이상의 열로 쉽게 확장 할 수 있다는 것 입니다.filter(across())
filter_at
와 솔루션도 아래 filter_all
에서 문자열 찾기 위해 어떤 사용하여 열을 diamonds
문자열 “V”를 찾고, 예를 들어
library(tidyverse)
하나의 열에 만있는 문자열
# for only one column... extendable to more than one creating a column list in `across` or `vars`!
mtcars %>%
rownames_to_column("type") %>%
filter(across(type, ~ !grepl('Toyota|Mazda', .))) %>%
head()
#> type mpg cyl disp hp drat wt qsec vs am gear carb
#> 1 Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
#> 2 Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
#> 3 Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
#> 4 Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
#> 5 Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
#> 6 Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
현재 대체 된 구문은 다음과 같습니다.
mtcars %>%
rownames_to_column("type") %>%
filter_at(.vars= vars(type), all_vars(!grepl('Toyota|Mazda',.)))
모든 열의 문자열 :
# remove all rows where any column contains 'V'
diamonds %>%
filter(across(everything(), ~ !grepl('V', .))) %>%
head
#> # A tibble: 6 x 10
#> carat cut color clarity depth table price x y z
#> <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
#> 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
#> 3 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
#> 4 0.3 Good J SI1 64 55 339 4.25 4.28 2.73
#> 5 0.22 Premium F SI1 60.4 61 342 3.88 3.84 2.33
#> 6 0.31 Ideal J SI2 62.2 54 344 4.35 4.37 2.71
현재 대체 된 구문은 다음과 같습니다.
diamonds %>%
filter_all(all_vars(!grepl('V', .))) %>%
head
나는 다음에 대한 대안을 찾으려고했지만 즉시 좋은 해결책을 찾지 못했습니다.
#get all rows where any column contains 'V'
diamonds %>%
filter_all(any_vars(grepl('V',.))) %>%
head
#> # A tibble: 6 x 10
#> carat cut color clarity depth table price x y z
#> <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
#> 1 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
#> 2 0.290 Premium I VS2 62.4 58 334 4.2 4.23 2.63
#> 3 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
#> 4 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47
#> 5 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53
#> 6 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49
업데이트 : 이 답변의 사용자 Petr Kajzar에게 감사드립니다 .
diamonds %>%
filter(rowSums(across(everything(), ~grepl("V", .x))) > 0)