#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)"