2014-10-16 2 views
4

У меня есть файл имен детей, которые я читаю, а затем пытаюсь получить последнего персонажа в имени ребенка. Например, файл выглядит как ..Использовать 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 

Я ve удалось разделить имя на отдельные символы.

sourceout = strsplit(as.character(sourcenames$Name),'') 

Но теперь, когда я застрял, как получить последнее письмо, так что в случае с Майклом, как получить «l». Я думал, что tail() может работать, но он возвращает последние несколько записей, а не последний символ в каждом элементе Name.

Любая помощь или совет приветствуются.

Спасибо :)

+0

Существует ответ, что здесь: http://stackoverflow.com/questions/77434/how-to-access-the-last-value-in-a-vector –

+2

Вы видели [это] (http://stackoverflow.com/questions/7963898/extracting-the-last-n-characters- from-a-string-in-r)? – kferris10

+0

http://stackoverflow.com/questions/7963898/extracting-the-last-n-characters-from-a-string-in-r – GSee

ответ

9

Для вашего метода 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" 
+0

Спасибо, это работает. Могу ли я спросить, как часть хвоста работает в sapply, как и параметры sapply(), это то, что я передаю хвост и значение 1 в. Я действительно новичок в R, так извиняюсь, если это глупый вопрос. – dataCruncher02

+1

Конечно. Вы применяете 'tail' итеративно через список 'strsplit', взяв элемент' 1' верхнего конца каждого вектора. '1' сообщает' tail', сколько элементов взять. По умолчанию шесть, что вы, вероятно, получаете –

1

Вы можете сделать это с помощью регулярных выражений и 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 
+0

Хорошо, используйте это. 'regex' удаляет метод' substr' из воды.2x скорость :-('unlist (Map (function (x) substring (x, nchar (x)), sourcenames $ Name))' – Vlo

2

Вот еще один вариант с использованием 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 
4

Попробуйте эту функцию из stringi пакета:

require(stringi) 
x <- c("Ala", "Sarah","Meg") 
stri_sub(x, from = -1, to = -1) 

Эта функция извлекает подстроки между от и до индекса. Если индексы отрицательные, тогда он подсчитывает символы от конца строки. Так что если 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 
2

Один лайнер:

x <- c("abc","123","Male") 
regmatches(x,regexpr(".$", x)) 
## [1] "c" "3" "e" 
0

dplyr подход:

sourcenames %>% rowwise() %>% mutate("Last Initial" = strsplit(as.character(Name),'') %>% unlist() %>% .[length(.)])