7

我有一个正在读取的婴儿姓名文件,然后尝试获取婴儿姓名中的最后一个字符。例如,文件看起来像..

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),'')

但现在我陷入困境的是如何获得最后一个字母,所以在迈克尔的情况下,如何获得“l”。我认为 tail() 可能有效,但它返回最后几条记录,而不是每个 Name 元素中的最后一个字符。

非常感谢任何帮助或建议。

谢谢 :)

4

7 回答 7

14

为了使您的strsplit方法起作用,您可以使用tailwithsapply

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"
于 2014-10-16T21:23:35.750 回答
7

stringi从包中尝试此功能:

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

此函数提取 from 和 to 索引之间的子字符串。如果索引为负数,则从字符串末尾开始计算字符。所以如果from=-1to=-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
于 2014-10-19T22:04:33.383 回答
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
于 2014-10-16T21:37:02.843 回答
2

一个班轮:

x <- c("abc","123","Male")
regmatches(x,regexpr(".$", x))
## [1] "c" "3" "e"
于 2015-01-04T10:57:38.367 回答
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
于 2014-10-16T20:53:14.793 回答
1

你可以试试这个...... stringr 包中的 str_sub() 函数会帮助你。

library(dplyr)
library(stringr)
library(babynames)
babynames %>%
  select(name,sex) %>%
  mutate(last_letter = str_sub(name,-1,-1)) %>%
  head()
于 2021-01-06T12:14:45.770 回答
0

dplyr方法:

sourcenames %>% rowwise() %>% mutate("Last Initial" = strsplit(as.character(Name),'') %>% unlist() %>% .[length(.)])
于 2017-03-08T02:02:20.690 回答