【问题标题】:R extract elements from string based on position of spacesR根据空格的位置从字符串中提取元素
【发布时间】:2018-09-26 10:46:04
【问题描述】:

我有一个数据框,其中包含基于上次修改日期的用户元数据。

数据框看起来像这样 -

dataframe=data.frame(Last_Modified=c("Peter Jones 11/02/1992 03:50:02 PM",
                                 "Veronika White  10/01/1996 13:12:00 AM",
                                 "Vincent Michaels  01/03/2008 12:01:00 PM"))

期望的输出

我想提取名称、日期和时间,并将它们存储在三个单独的列中,称为NameDateTime

例如,第一行"Peter Jones 11/02/1992 03:50:02 PM" 将被分解为三个附加列,其中NamePeter JonesDate11/02/1992Time03:50:02 PM .其余行也一样。

我的尝试

我正在尝试使用分隔每个实体的空格作为拆分方式。 根据之前的帖子,我尝试使用以下行的变体。但这并没有返回我想要的输出。

sub("^\\S+\\s+", '', dataframe$Last_Modified)

对此的任何帮助将不胜感激。

【问题讨论】:

  • 如果每个条目的整体格式相同,可以使用strsplit命令

标签: r split


【解决方案1】:

数据:

df1 = data.frame(Last_Modified=c("Peter Jones 11/02/1992 03:50:02 PM",
                                     "Veronika White  10/01/1996 13:12:00 AM",
                                     "Vincent Michaels  01/03/2008 12:01:00 PM"), stringsAsFactors = F)

代码:

ans <- strsplit(df1$Last_Modified, "\\s+(?=\\d)", perl = T)

ans <- as.data.frame(do.call(rbind, ans), stringsAsFactors = F)
names(ans) <- c("Name", "Date", "Time")

结果:

#              Name       Date        Time
#1      Peter Jones 11/02/1992 03:50:02 PM
#2   Veronika White 10/01/1996 13:12:00 AM
#3 Vincent Michaels 01/03/2008 12:01:00 PM

请注意:

  • 您命名您的数据框数据框。不要使用保留语言关键字作为变量名
  • 使用您的示例数据,字符被转换为因子:READ THIS
  • \\s+(?=\\d) 模式使用积极的前瞻性。阅读并了解正则表达式中的正向前瞻性。

【讨论】:

    【解决方案2】:

    这是另一个使用 sub 的基本 R 选项:

    df = data.frame(Last_Modified=c("Peter Jones 11/02/1992 03:50:02 PM",
                                    "Veronika White  10/01/1996 13:12:00 AM",
                                    "Vincent Michaels  01/03/2008 12:01:00 PM"),
                    stringsAsFactors=FALSE)
    
    df$Name <- sub("(.*?)(?= \\d).*", "\\1", df$Last_Modified, perl=TRUE)
    df$Date <- sub(".*(\\d{2}/\\d{2}/\\d{4}).*", "\\1", df$Last_Modified, perl=TRUE)
    df$Time <- sub(".*(\\d{2}:\\d{2}:\\d{2} (?:AM|PM))", "\\1", df$Last_Modified, perl=TRUE)
    df[c("Name", "Date", "Time")]
    
                   Name       Date        Time
    1       Peter Jones 11/02/1992 03:50:02 PM
    2   Veronika White  10/01/1996 13:12:00 AM
    3 Vincent Michaels  01/03/2008 12:01:00 PM
    

    Demo

    【讨论】:

      【解决方案3】:

      您也可以使用带有一些正则表达式的stringi 包:

      library(stringi)
      
      dataframe=data.frame(Last_Modified=c("Peter Jones 11/02/1992 03:50:02 PM",
                                           "Veronika White  10/01/1996 13:12:00 AM",
                                           "Vincent Michaels  01/03/2008 12:01:00 PM"))
      
      
      name_part <- stri_match_last_regex(dataframe$Last_Modified, pattern = "^[A-Za-z ]*\\d")
      dataframe$Name <- lapply(name_part, function(x) { trimws(stri_sub(x, 1, length = nchar(x) - 2))})
      dataframe$Date <- stri_match_last_regex(dataframe$Last_Modified, pattern = "\\d\\d/\\d\\d/\\d\\d\\d\\d")
      dataframe$Time <- stri_match_last_regex(dataframe$Last_Modified, pattern = "\\d\\d:\\d\\d:\\d\\d [AP]M")
      
      dataframe
      

      【讨论】:

        【解决方案4】:

        将空格后跟数字替换为逗号后跟相同数字,然后将read.tablesep="," 一起使用:

        read.table(text = gsub(" +(\\d)", ",\\1", dataframe[[1]]), 
         sep = ",", col.names = c("Name", "Date", "Time"), as.is = TRUE, strip.white = TRUE)
        

        给予:

                      Name       Date        Time
        1      Peter Jones 11/02/1992 03:50:02 PM
        2   Veronika White 10/01/1996 13:12:00 AM
        3 Vincent Michaels 01/03/2008 12:01:00 PM
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-06-22
          • 1970-01-01
          • 2019-12-10
          • 2019-03-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多