Как определить, заканчивается ли строка "заканчивается" другой строкой в ​​R?

Я хочу отфильтровать строки таблицы, которые содержат "*" в строковом значении столбца. Проверка только этой колонки.

 string_name = c("aaaaa", "bbbbb", "ccccc", "dddd*", "eee*eee")

 zz <- sapply(tx$variant_full_name, function(x) {substrRight(x, -1) =="*"})
 Error in FUN(c("Agno I30N", "VP2 E17Q", "VP2 I204*", "VP3 I85F", "VP1 K73R",  : 
   could not find function "substrRight"

Четвертое значение zz должно быть TRUE этим.

в python есть функция endswith для строк [string_s.endswith('*')] Есть ли что-то подобное в R?

Кроме того, это проблема из-за '*' как символа, поскольку это означает любой символ? grepl также не работает.

> grepl("*^",'dddd*')
[1] TRUE
> grepl("*^",'dddd')
[1] TRUE

Ответ 1

* является quantifier в регулярных выражениях. Он сообщает движку регулярных выражений попытаться сопоставить предыдущий токен "ноль или более раз". Чтобы соответствовать литералу, вам нужно перед ним выполнить две обратные косые черты или помещать внутри класса символов [*]. Чтобы проверить, заканчивается ли строка с определенным шаблоном, используйте конец строки $ anchor.

> grepl('\\*$', c('aaaaa', 'bbbbb', 'ccccc', 'dddd*', 'eee*eee'))
# [1] FALSE FALSE FALSE  TRUE FALSE

Вы можете просто сделать это, не применяя регулярное выражение в базе R:

> x <- c('aaaaa', 'bbbbb', 'ccccc', 'dddd*', 'eee*eee')
> substr(x, nchar(x)-1+1, nchar(x)) == '*'
# [1] FALSE FALSE FALSE  TRUE FALSE

Ответ 2

Это достаточно просто, что вам не нужны регулярные выражения.

> string_name = c("aaaaa", "bbbbb", "ccccc", "dddd*", "eee*eee")
> substring(string_name, nchar(string_name)) == "*"
[1] FALSE FALSE FALSE  TRUE FALSE

Ответ 3

Я использую что-то вроде этого:

strEndsWith <- function(haystack, needle)
{
  hl <- nchar(haystack)
  nl <- nchar(needle)
  if(nl>hl)
  {
    return(F)
  } else
  {
    return(substr(haystack, hl-nl+1, hl) == needle)
  }
}

Ответ 4

База теперь содержит startsWith и endsWith. Таким образом, на вопрос ОП можно ответить endsWith:

> string_name = c("aaaaa", "bbbbb", "ccccc", "dddd*", "eee*eee")
> endsWith(string_name, '*')
[1] FALSE FALSE FALSE  TRUE FALSE

Это намного быстрее, чем substring(string_name, nchar(string_name)) == '*'.