Наиболее декларативный подход для извлечения данных из строк - PullRequest
1 голос
/ 05 ноября 2019

Я хотел бы извлечь данные из строк.

Ввод:

d <- c("\n      98.000 € VB\n          \n      99999\n          K9mm999u", 
    "\n      9 € VB\n          \n      89999\n          Di9ß99", 
    "\n      900.000 €\n          \n      89999\n          Aich9ch", 
    "\n      979.000 € VB\n          \n      98999\n          Ni9999rg9", 
    "\n      979.000 €\n          \n      99999\n          F9lk99s99"
    )

Желаемый вывод:

[[1]]
[1] "99999"    "K9mm999u"

[[2]]
[1] "89999"  "Di9ß99"

[[3]]
[1] "89999"   "Aich9ch"

[[4]]
[1] "98999"     "Ni9999rg9"

[[5]]
[1] "99999"     "F9lk99s99"

Что я пробовал:

library(magrittr)
d %>% gsub(pattern = ".*€|VB|\n", replacement = "", fixed = FALSE) %>% 
  trimws %>% strsplit(split = "          ")

Иногда это работало бы, но часть strsplit(split = " ") кажется довольно плохой.

Если все в порядке, я бы спросилболее общие:

Я бы пошел с:

filter <- function(result) result[sapply(result, nchar) > 0]
d %>% gsub(pattern = ".*€|VB|\n", replacement = "", fixed = FALSE) %>% 
  trimws %>% strsplit(split = " ") %>% lapply(FUN = filter)

Но нужно ли определять эту пользовательскую filter функцию.

Вопрос:

Каков наиболее декларативный подход для получения желаемого результата?

1 Ответ

1 голос
/ 05 ноября 2019

В коде ОП strsplit с одним или несколькими пробелами можно изменить на \\s+

library(dplyr)
d %>% 
   gsub(pattern = ".*€|VB|\n", replacement = "", fixed = FALSE) %>% 
   trimws %>% 
   strsplit(split = "\\s+")
#[[1]]
#[1] "99999"    "K9mm999u"

#[[2]]
#[1] "89999"  "Di9ß99"

#[[3]]
#[1] "89999"   "Aich9ch"

#[[4]]
#[1] "98999"     "Ni9999rg9"

#[[5]]
#[1] "99999"     "F9lk99s99"

Вот еще один вариант с read.table из base R, где мы читаем'd' в data.frame, извлечение первого столбца, использование логического вектора рециркуляции для подстановки элементов и split в list с asplit

asplit(matrix(read.table(text = d, header = FALSE, fill = TRUE, 
  stringsAsFactors = FALSE)$V1[c(FALSE, TRUE, TRUE)], ncol = 2, byrow = TRUE), 1)
#[[1]]
#[1] "99999"    "K9mm999u"

#[[2]]
#[1] "89999"  "Di9ß99"

#[[3]]
#[1] "89999"   "Aich9ch"

#[[4]]
#[1] "98999"     "Ni9999rg9"

#[[5]]
#[1] "99999"     "F9lk99s99"

илис regmatches/gregexpr из base R, соответствуют либо 5-значным числам ([0-9]{5}), либо (|) буквенно-цифровым символам длиной 5 и более ([[:alnum:]]{5,}), извлекаются в list. \\b относится к границе слова

regmatches(d, gregexpr("\\b[0-9]{5}\\b|\\b[[:alnum:]]{5,}\\b", d))
#[[1]]
#[1] "99999"    "K9mm999u"

#[[2]]
#[1] "89999"  "Di9ß99"

#[[3]]
#[1] "89999"   "Aich9ch"

#[[4]]
#[1] "98999"     "Ni9999rg9"

#[[5]]
#[1] "99999"     "F9lk99s99"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...