Используйте strsplit, чтобы получить последний символ в r
У меня есть файл с именами детей, которые я читаю, а затем пытаюсь получить последний символ имени ребенка. Например, файл выглядит так..
Name Sex
Anna F
Michael M
David M
Sarah F
Я прочитал это в использовании
sourcenames = read.csv("babynames.txt", header=F, sep=",")
В конечном итоге я хочу, чтобы мой результат выглядел как...
Name Last Initial Sex
Michael l M
Sarah h F
Мне удалось разделить имя на отдельных персонажей..
sourceout = strsplit(as.character(sourcenames$Name),'')
Но сейчас я застрял в том, как получить последнюю букву, а в случае с Майклом, как получить "я". Я думал, что tail() может работать, но он возвращает последние несколько записей, а не последний символ в каждом элементе Name.
Любая помощь или совет с благодарностью.
Спасибо:)
7 ответов
Для тебя strsplit
метод для работы, вы можете использовать tail
с sapply
df$LastInit <- sapply(strsplit(as.character(df$Name), ""), tail, 1)
df
# Name Sex LastInit
# 1 Anna F a
# 2 Michael M l
# 3 David M d
# 4 Sarah F h
Кроме того, вы можете использовать substring
with(df, substring(Name, nchar(Name)))
# [1] "a" "l" "d" "h"
Попробуйте эту функцию из stringi
пакет:
require(stringi)
x <- c("Ala", "Sarah","Meg")
stri_sub(x, from = -1, to = -1)
Эта функция извлекает подстроки между from и to index. Если индексы отрицательные, то он считает символы с конца строки. Так что если from=-1
а также to=-1
это означает, что мы хотим подстроку от последнего до последнего символа:)
Зачем использовать stringi
? Просто посмотрите на этот тест:)
require(microbenchmark)
x <- sample(x,1000,T)
microbenchmark(stri_sub(x,-1), str_extract(x, "[a-z]{1}$"), gsub(".*(.)$", "\\1", x),
sapply(strsplit(as.character(x), ""), tail, 1), substring(x, nchar(x)))
Unit: microseconds
expr min lq median uq max neval
stri_sub(x, -1) 56.378 63.4295 80.6325 85.4170 139.158 100
str_extract(x, "[a-z]{1}$") 718.579 764.4660 821.6320 863.5485 1128.715 100
gsub(".*(.)$", "\\\\1", x) 478.676 493.4250 509.9275 533.8135 673.233 100
sapply(strsplit(as.character(x), ""), tail, 1) 12165.470 13188.6430 14215.1970 14771.4800 21723.832 100
substring(x, nchar(x)) 133.857 135.9355 141.2770 147.1830 283.153 100
Один лайнер:
x <- c("abc","123","Male")
regmatches(x,regexpr(".$", x))
## [1] "c" "3" "e"
Вот еще один вариант, использующий data.table (для относительно чистого синтаксиса) и stringr (более простая грамматика).
library(data.table); library(stringr)
df = read.table(text="Name Sex
Anna F
Michael M
David M
Sarah F", header=T)
setDT(df) # convert to data.table
df[, "Last Initial" := str_extract(Name, "[a-z]{1}$") ][]
Name Sex Last Initial
1: Anna F a
2: Michael M l
3: David M d
4: Sarah F h
вы можете попробовать это... функция str_sub() в пакете stringr вам поможет.
library(dplyr)
library(stringr)
library(babynames)
babynames %>%
select(name,sex) %>%
mutate(last_letter = str_sub(name,-1,-1)) %>%
head()
Вы можете сделать это с помощью регулярного выражения и gsub
:
sourcenames$last.letter = gsub(".*(.)$", "\\1", sourcenames$Name)
sourcenames
Name Sex last.letter
1 Anna F a
2 Michael M l
3 David M d
4 Sarah F h
dplyr
подход:
sourcenames %>% rowwise() %>% mutate("Last Initial" = strsplit(as.character(Name),'') %>% unlist() %>% .[length(.)])