использование регулярных выражений в Tidyverse для фильтрации - неясно, почему это не работает - PullRequest
0 голосов
/ 01 ноября 2019

Я пытаюсь отфильтровать строки, содержащие строку "Data\\this\\way\\test". Неясно, почему это не работает. В идеале ожидалось бы увидеть вывод типа

  "D:\\Data\\this\\way\\test\\dat1",
  "D:\\Data\\this\\way\\test\\dat2",

Мой код:

files <- c(
  "D:\\Data\\this\\way\\test\\dat1",
  "D:\\Data\\this\\way\\test\\dat2",
  "D:\\Data\\not-this\\way\\test\\dat1",
  "D:\\Data\\not-this\\way\\test\\dat2"
)

files_filt_df <- data.frame(filenames = files, 
                             stringsAsFactors = FALSE) %>%
  filter(str_detect(filenames,"Data\\this\\way\\test"))
files_filt_df
[1] filenames
<0 rows> (or 0-length row.names)

Ответы [ 3 ]

2 голосов
/ 02 ноября 2019

Поскольку это имена файлов, вы также можете использовать пакет fs, чтобы проверить, имеет ли файл определенный родительский элемент, и позволить fs иметь дело с разделителями файлов.

library("tidyverse")

files <- c(
  "D:\\Data\\this\\way\\test\\dat1",
  "D:\\Data\\this\\way\\test\\dat2",
  "D:\\Data\\not-this\\way\\test\\dat1",
  "D:\\Data\\not-this\\way\\test\\dat2"
)

tibble(
  file = files
) %>%
  filter(map_lgl(file, ~ fs::path_has_parent(., "D:/Data/this/way")))
#> # A tibble: 2 x 1
#>   file                             
#>   <chr>                            
#> 1 "D:\\Data\\this\\way\\test\\dat1"
#> 2 "D:\\Data\\this\\way\\test\\dat2"

# Explanation:

# The `map_lgl` applies `fs::path_has_parent` to each file
# and returns TRUE/FALSE (logical = lgl) values.

# Without `map`:
fs::path_has_parent(files, "D:/Data/this/way")
#> [1] FALSE

# With `map`:
map_lgl(files, ~ fs::path_has_parent(., "D:/Data/this/way"))
#> [1]  TRUE  TRUE FALSE FALSE

# The `~` operator creates a formula.
# Here it is shorter than defining an inline function.

# Formula:
map_lgl(files, ~ fs::path_has_parent(., "D:/Data/this/way"))
#> [1]  TRUE  TRUE FALSE FALSE

# Function:
map_lgl(files, function(x) fs::path_has_parent(x, "D:/Data/this/way"))
#> [1]  TRUE  TRUE FALSE FALSE

Созданона 2019-11-02 пакетом представьте (v0.3.0)

2 голосов
/ 02 ноября 2019

По умолчанию str_detect ожидает, что вы передадите регулярное выражение. Такие вещи, как \w, имеют особое значение в регулярных выражениях. Если вы просто хотите сопоставить литеральное значение, самый простой способ будет

files_filt_df <- data.frame(filenames = files, 
                            stringsAsFactors = FALSE) %>%
  filter(str_detect(filenames,fixed("Data\\this\\way\\test")))

. Или, если вы хотите использовать регулярное выражение, вам нужно добавить дополнительный уровень экранирования в слешах

files_filt_df <- data.frame(filenames = files, 
                            stringsAsFactors = FALSE) %>%
  filter(str_detect(filenames,"Data\\\\this\\\\way\\\\test"))
0 голосов
/ 05 ноября 2019

Решение Base R (найти буквенный шаблон в файлах, вернуть все значения, соответствующие шаблону):

data.frame(files = grep("\\Data\\this\\way\\", files, value = T, fixed = T), stringsAsFactors = F)
...