R根据空格位置从字符串中提取元素

时间:2018-09-26 10:46:04

标签: r split

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

数据框看起来像这样-

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 JonesDate为{{1 }}和11/02/1992设为Time。其余的行也一样。

我的尝试

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

03:50:02 PM

对此将提供任何帮助。

4 个答案:

答案 0 :(得分:2)

数据:

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)模式使用积极的眼光。阅读并了解正则表达式中的正面展望。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

您还可以将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

答案 3 :(得分:1)

用空格后跟逗号,然后用相同的数字替换空格,然后将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