Индекс последнего пробела в каждом элементе вектора символов - PullRequest
0 голосов
/ 18 марта 2019

У меня есть символьный вектор x как

 [1] "Mt. Everest" "Cho oyu" "Mont Blanc" "Ojos del Salado"

И я ищу вывод, дающий мне индекс последнего пробела

[1] 4 4 5 9

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

sapply(x,myFunction)

Для myFunction я пишу что-то вроде:

myFunction <- function(a){
match(a,c(" "))
}

, чтопо понятным причинам выдает все NA, поскольку ни один элемент не является пробелом.

Я не хочу использовать для этого stringr.

Ответы [ 6 ]

1 голос
/ 18 марта 2019

Вы можете добиться этого, используя gregexpr

x = c("Mt. Everest", "Cho oyu", "Mont Blanc", "Ojos del Salado")

lapply(gregexpr(pattern=" ", x), max)

Если вы хотите, чтобы ваш ответ был векторным

> sapply(gregexpr(pattern=" ", x), max)
[1] 4 4 5 9

Кредит: Ответ был улучшен с помощью @ markus

1 голос
/ 18 марта 2019

regexpr будет делать ...

v <- c("Mt. Everest", "Cho oyu", "Mont Blanc", "Ojos del Salado")

#find position of space, not followed by a space until the end of string    
regexpr(" [^ ]*$", v)

#int [1:4] 4 4 5 9

или

library(dplyr)
data.frame( v = v ) %>% mutate( lastspace = regexpr(" [^ ]*$", v) )

#                 v lastspace
# 1     Mt. Everest         4
# 2         Cho oyu         4
# 3      Mont Blanc         5
# 4 Ojos del Salado         9
1 голос
/ 18 марта 2019

Одним из способов использования mapply является разбиение символов на пробел, вычисление количества символов последнего элемента и вычитание его из общего количества символов в строке.

myFunction <- function(a){
  mapply(function(p, q) q - nchar(p[length(p)]), strsplit(a, "\\s+"), nchar(a))
}  

myFunction(x)
#[1] 4 4 5 9

Как это работает:

Давайте возьмем последний элемент из списка:

x <- "Ojos del Salado"

#Split on whitespace
p = strsplit(x, "\\s+")[[1]]
p
#[1] "Ojos"   "del"    "Salado"

#Select the last element 
p[length(p)]
#[1] "Salado"

#Count the number of characters in the last element
nchar(p[length(p)])
#[1] 6

#Subtract it from total characters in x
nchar(x) - nchar(p[length(p)])
#[1] 9

data

x <- c("Mt. Everest", "Cho oyu" ,"Mont Blanc", "Ojos del Salado")
0 голосов
/ 18 марта 2019

Простая и лаконичная альтернатива

sapply(a,function(x){last(which(strsplit(x,"")[[1]]==" "))})

    Mt. Everest         Cho oyu      Mont Blanc Ojos del Salado 
              4               4               5               9 
0 голосов
/ 18 марта 2019

Вы также можете попробовать grepRaw():

sapply(x, function(x) max(grepRaw(" ", x, all = TRUE)))

Mt. Everest         Cho oyu      Mont Blanc Ojos del Salado 
          4               4               5               9 

С dplyr:

data.frame(x) %>%
 mutate(res = sapply(x, function(x) max(grepRaw(" ", x, all = TRUE))))

                x res
1     Mt. Everest   4
2         Cho oyu   4
3      Mont Blanc   5
4 Ojos del Salado   9
0 голосов
/ 18 марта 2019

Использование stringr:

library(stringr)
myFunction <- function(a){
  str_locate(a, " (?=[^ ]*$)")[, 1]
}

myFunction(x)
# [1] 4 4 5 9

Используя stringi (и избегая регулярных выражений):

library(stringi)
myFunction2 <- function(a){
  stri_locate_last_fixed(a, " ")[, 1]
}

myFunction2(x)
# [1] 4 4 5 9

Используя strsplit() из базы R (и избегая также регулярных выражений):

myFunction3 <- function(a){
  sapply(strsplit(x, ""), function(x) max(which(x == " ")))
}

myFunction3(x)
# [1] 4 4 5 9

Данные:

x <- c("Mt. Everest", "Cho oyu", "Mont Blanc", "Ojos del Salado")
...