str_detect () и map () для перебора множества обнаружений строк - PullRequest
0 голосов
/ 12 июля 2020

Мои данные в формате ниже. (Код для ввода данных в самом конце, вопрос ниже).

#> df
#>  id amount description
#>   1     10 electricity
#>   2    100        rent
#>   3      4        fees

Я хотел бы иметь возможность классифицировать транзакции (строки) в зависимости от того, есть ли в описании определенные строки.

Так, например:

library(tidyverse)
df <- df %>% 
  mutate(category = ifelse(str_detect(description, "elec"), "bills", description))

, что дает:

#>   id amount description category
#> 1  1     10 electricity    bills
#> 2  2    100        rent         
#> 3  3      4        fees

Я хотел бы иметь возможность определять вектор ключевых слов и связанные категории, как показано ниже:

keywords <- c(electric = "bills",
              rent = "bills",
              fees = "misc")

Каков следующий шаг, чтобы создать столбец категорий с правильными метками?

Желаемый результат:


#>   id amount description category
#> 1  1     10 electricity    bills
#> 2  2    100        rent    bills         
#> 3  3      4        fees    misc

Я пробовал map2_df, но я, должно быть, делаю что-то не так, потому что приведенный ниже код создает три версии df, наложенные друг на друга:

categorise_transactions <- function(keyword, category){df <- df %>% 
  mutate(category = ifelse(str_detect(description, keyword), category, description))}

library(purrr)
map2_df(names(keywords), keywords, categorise_transactions)

код для ввода данных ниже:

df <- data.frame(
  stringsAsFactors = FALSE,
                id = c(1L, 2L, 3L),
            amount = c(10L, 100L, 4L),
       description = c("electricity", "rent", "fees")
)
df

1 Ответ

3 голосов
/ 12 июля 2020

str_replace_all почти дает то, что вам нужно:

library(dplyr)
library(stringr)

str_replace_all(df$description, keywords)
#[1] "billsity" "bills"    "misc" 

Однако, как предлагает @Russ Thomas, case_when дает именно то, что вам нужно.

library(dplyr)
library(stringr)

df %>%
  mutate(category = case_when(str_detect(description, 'electric') ~ 'bills', 
                              str_detect(description, 'rent') ~ 'bills', 
                              str_detect(description, 'fees') ~ 'misc'))  


#  id amount description category
#1  1     10 electricity    bills
#2  2    100        rent    bills
#3  3      4        fees     misc 
...