Подмножество списка строк по первому слову

#r #string #list

#r #строка #Список

Вопрос:

Возможно ли подмножество списка строк, например, List[1:3], используя grepl? Я хочу определить первое слово в символьной строке, чтобы начать индекс и закончить индекс первым словом строки, которое соответствует.

Причина, по которой я не хочу использовать числовой индекс, заключается в том, что я планирую подмножество нескольких PDF-файлов финансовых отчетов, и они могут отличаться с точки зрения того, что содержится в списке.

Вот данные, которые у меня есть:

 list(c("CASH $99,999,999.00 $99,999,999.00 0.00"), 
    c("CASH SLIPS 1,000,000.00 1,000,000.00 0.00"), 
    c("BONDS 500,000.00 (500,000.00)"), 
    c("ACCOUNTS RECEIVABLE 1,000,000.00 2,000,000.00 (1,000,000.00)"))
  

Как бы я подмножил, начав с НАЛИЧНЫХ, то есть с точного соответствия, а не с КАССОВЫХ ЧЕКОВ, и закончив ОБЛИГАЦИЯМИ?

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

 list(c("CASH $99,999,999.00 $99,999,999.00 0.00"), 
        c("CASH SLIPS 1,000,000.00 1,000,000.00 0.00"), 
        c("BONDS 500,000.00 (500,000.00)"))
  

Комментарии:

1. Ваш желаемый список отображается CASH SLIPS , в то время как описание . the exact match, not CASH SLIPS,

2. Когда я пытался использовать reply, я заметил, что он сопоставляет как наличные, так и КАССОВЫЕ ЧЕКИ. Итак, ваш ответ — это то, что я искал.

Ответ №1:

Мы можем использовать Filter из base R

 Filter(function(x) grepl("^(CASH|BONDS)", x), lst1)
#[[1]]
#[1] "CASH $99,999,999.00 $99,999,999.00 0.00"

#[[2]]
#[1] "CASH SLIPS 1,000,000.00 1,000,000.00 0.00"

#[[3]]
#[1] "BONDS 500,000.00 (500,000.00)"
  

Или другой вариант, если мы хотим подмножество на основе начального индекса ‘CASH’ и конечного индекса ‘BONDS’

 i1 <- sub("\s [^A-Z] ", "", unlist(lst1)) %in% c("CASH", "BONDS")
lst1[Reduce(`:`, as.list(range(which(i1))))]
#[[1]]
#[1] "CASH $99,999,999.00 $99,999,999.00 0.00"

#[[2]]
#[1] "CASH SLIPS 1,000,000.00 1,000,000.00 0.00"

#[[3]]
#[1] "BONDS 500,000.00 (500,000.00)"
  

Или с помощью grepl

 lst1[Reduce(`:`, as.list(range(grep("^(CASH|BONDS)\s ([^A-Z])", unlist(lst1)))))]
#[[1]]
#[1] "CASH $99,999,999.00 $99,999,999.00 0.00"

#[[2]]
#[1] "CASH SLIPS 1,000,000.00 1,000,000.00 0.00"

#[[3]]
#[1] "BONDS 500,000.00 (500,000.00)"
  

или с помощью keep из purrr

 library(stringr)
library(purrr)
keep(lst1, ~ str_detect(.x, '^(CASH|BONDS)'))
  

Или с sapply и word

 lst1[sapply(lst1, word, 1) %in% c("CASH", "BONDS")]
  

Ответ №2:

Вы можете извлекать слова до тех пор, пока для каждого списка не встретится число или "$" знак.

 first_word <- sapply(data, function(x) sub('(.*?)\s(\d |\$).*', '\1', x))
first_word
#[1] "CASH"    "CASH SLIPS"     "BONDS"    "ACCOUNTS RECEIVABLE"
  

и используйте их first_word , чтобы выбрать элементы из списка, которые начинаются с "CASH" и заканчиваются на "BONDS" .

 data[which(first_word == 'CASH'):which(first_word == 'BONDS')]

#[[1]]
#[1] "CASH $99,999,999.00 $99,999,999.00 0.00"

#[[2]]
#[1] "CASH SLIPS 1,000,000.00 1,000,000.00 0.00"

#[[3]]
#[1] "BONDS 500,000.00 (500,000.00)"