【问题标题】:Split a Column Into 2 Using Regular Expression使用正则表达式将一列拆分为 2
【发布时间】:2017-09-12 20:54:01
【问题描述】:

我有一个包含时间的数据框,格式如下:

df<-data.frame(time=c("1655","1055","1123","1505"))
#   time
# 1 1655
# 2 1055
# 3 1123
# 4 925

我想把它改成标准格式,即带冒号的 16:55:00,但是在 lubridate 包中使用函数 hms 不起作用。

我正在考虑将 time 列分成 2 列,这样我就可以:

#   time1 time2
# 1 16    55
# 2 10    55
# 3 11    23
# 4  9    25

然后使用:作为分隔符将它们组合回来:

#   time
# 1 16:55
# 2 10:55
# 3 11:23
# 4 09:25

但是,我不确定该怎么做(尤其是处理正则表达式)。我试过了:

library(tidyr)
df %>% 
separate(time,c("time1","time2"),sep="[[:digit:]$]{2}") %>%
unite(time,time1,time,sep=":")

当然,这是行不通的。

【问题讨论】:

    标签: r dplyr tidyr lubridate


    【解决方案1】:

    如果您确实想使用lubridate 将时间存储为Period,您可以使用类似以下的内容

    df<-data.frame(time=c("1655","1055","1123","1505","955"))
    df$time2 <- hm(gsub("(.{2}$)",":\\1",df$time))
    

    gsub 在最后两个字符前插入一个“:”

    hm from lubridate 将其转换为 Period 对象。

    【讨论】:

      【解决方案2】:

      我们可以使用sprintf将3位数字转换为4位数字,方法是在开头附加0,然后用sub匹配开头的两个字符并捕获为一个组((.{2}))并替换它带有反向引用 (\\1),后跟 :

      df$time <- sub("^(.{2})", "\\1:", sprintf("%04d", as.integer(as.character(df$time))))
      df$time
      #[1] "16:55" "10:55" "11:23" "09:25"
      

      或者另一个选项是str_pad from stringr

      library(stringr)
      sub("(.{2})$", ":\\1", str_pad(df$time, 4, "left", pad = "0"))
      #[1] "16:55" "10:55" "11:23" "09:25"
      

      如果我们更喜欢tidyverse,如果我们先将mutatesprintf 一起使用,separate/unite 也可以工作

      library(tidyverse)
      df %>% 
           mutate(time = sprintf("%04d", as.integer(as.character(time)))) %>% 
           separate(time, into = c("time1", "time2"), sep=2) %>%
           unite(time, time1, time2, sep=":")
      #    time
      #1 16:55
      #2 10:55
      #3 11:23
      #4 09:25
      

      或使用str_pad/str_replace 来自stringr

      df %>%
         mutate(time = str_pad(time, 4, "left", pad = "0"),
                time = str_replace(time, "(.{2})", "\\1:"))
      #   time
      #1 16:55
      #2 10:55
      #3 11:23
      #4 09:25
      

      数据

      df <- data.frame(time=c("1655","1055","1123","925"))
      

      注意:在不使用 stringsAsFactors 的情况下创建 data.frame 将默认使用 stringsAsFactors=TRUE 因此带有 factor 的列,它会转换为 integeras.integer(as.character 以用作 @987654345 的输入@

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-25
        • 2018-04-06
        • 2021-04-23
        • 2020-08-07
        • 2021-06-26
        • 1970-01-01
        • 2021-01-19
        • 1970-01-01
        相关资源
        最近更新 更多