【问题标题】:Use strsplit to get last character in r使用 strsplit 获取 r 中的最后一个字符
【发布时间】:2014-12-12 08:46:22
【问题描述】:

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

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 元素中的最后一个字符。

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

谢谢:)

【问题讨论】:

标签: regex r string parsing strsplit


【解决方案1】:

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

library(dplyr)
library(stringr)
library(babynames)
babynames %>%
  select(name,sex) %>%
  mutate(last_letter = str_sub(name,-1,-1)) %>%
  head()

【讨论】:

    【解决方案2】:

    dplyr 方法:

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

    【讨论】:

      【解决方案3】:

      stringi 包中试试这个功能:

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

      此函数提取从索引到索引之间的子字符串。如果索引为负数,则从字符串末尾开始计算字符。所以如果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
      

      【讨论】:

        【解决方案4】:

        一个班轮:

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

        【讨论】:

          【解决方案5】:

          这是另一个使用 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
          

          【讨论】:

            【解决方案6】:

            为了使您的strsplit 方法起作用,您可以将tailsapply 一起使用

            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"
            

            【讨论】:

            • 谢谢,这是一种享受。我可以问一下尾巴部分在 sapply 中是如何工作的,比如我将 tail 和值 1 传递给 sapply() 的哪些参数。如果这是一个愚蠢的问题,我真的很抱歉。
            • 当然。您通过strsplit 列表迭代地应用tail,获取每个向量尾部的1st 元素。 1 告诉tail 需要多少元素。默认值为 6,这可能是您得到的
            【解决方案7】:

            您可以使用正则表达式和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
            

            【讨论】:

            • 好用这个。 regexsubstr 方法吹出水面。 2 倍速度 :-( unlist(Map(function(x) substring(x, nchar(x)), sourcenames$Name))
            猜你喜欢
            • 1970-01-01
            • 2018-11-28
            • 1970-01-01
            • 2022-12-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-06
            • 1970-01-01
            相关资源
            最近更新 更多