【问题标题】:regex to split on anything not a digit正则表达式拆分任何不是数字的东西
【发布时间】:2015-07-16 15:03:38
【问题描述】:

我想在任何非数字上分割字符串。在这种特殊情况下,字符串是从外部.csv 文件中读取的日期和时间,当前不是as.POSIXct 格式。

理想情况下,我想使用regex 拆分字符串,但如果有更简单的方法可以使用date / time 函数将它们转换为六列数字,那也会很有趣。

我已经成功创建了一个regex,它将字符串分成六列,但是这个regex并不通用。

以下是数据:

my.data <- read.csv(text = '
          Date_Time
    18/05/2011 07:32:40
    19/05/2011 13:26:02
    19/05/2011 13:32:47
    19/05/2011 13:45:24
    19/05/2011 14:57:27
    19/05/2011 15:03:18
', header=TRUE, stringsAsFactors = FALSE, na.strings = 'NA', strip.white = TRUE)

这是一个regex 语句,它将字符串分成六列:

my.date.time <- data.frame(do.call(rbind, strsplit(my.data$Date_Time,"[/|:|[:space:]]+") ))

上述说法并不笼统。这是通过在任何非数字上指定拆分来使 regex 通用的不成功尝试:

data.frame(do.call(rbind, strsplit(my.data$Date_Time,"[^\\d]+") ))

在我将字符串分成六列后,我仍然需要看起来过多的语句来将列转换为数字格式:

colnames(my.date.time) <- c('my.day', 'my.month', 'my.year', 'my.hour', 'my.minute', 'my.second')

revised.data <- data.frame(my.data, my.date.time, stringsAsFactors = FALSE)

revised.data$my.day    <- as.numeric(as.character(revised.data$my.day))
revised.data$my.month  <- as.numeric(as.character(revised.data$my.month))
revised.data$my.year   <- as.numeric(as.character(revised.data$my.year))
revised.data$my.hour   <- as.numeric(as.character(revised.data$my.hour))
revised.data$my.minute <- as.numeric(as.character(revised.data$my.minute))
revised.data$my.second <- as.numeric(as.character(revised.data$my.second))
revised.data

str(revised.data)

感谢您在概括上述regex(或使用date / time 函数简化程序)方面提供的任何帮助。 apply 函数可能可以消除大部分 as.numeric(as.character) 语句,尽管这是一个相对较小的问题。

【问题讨论】:

  • [^\\d] 不工作?
  • @drmariod 不。它只是返回空白。
  • apply(my.data, 1, strsplit, "[^[:digit:]]"),之后就是我认为的unlist和rbind结果的问题。
  • @SabDeM 谢谢。这样可行。考虑将其发布为答案。如果不接受,我会投票。
  • @MarkMiller 好的,我已经发布了最终输出。

标签: regex r string datetime split


【解决方案1】:

试试\\D+

> x <- "18/05/2011 07:32:40"
> strsplit(x, "\\D+")
[[1]]
[1] "18"   "05"   "2011" "07"   "32"   "40" 

> strsplit(x, "[^0-9]+")
[[1]]
[1] "18"   "05"   "2011" "07"   "32"   "40" 

【讨论】:

    【解决方案2】:

    也许我错过了什么,但这是我的解决方案:

    lisda <- apply(my.data, 1, strsplit, "[^[:digit:]]")
    my.data2 <- t(data.frame(lisda))
    my.data2
                [,1] [,2] [,3]   [,4] [,5] [,6]
    Date_Time   "18" "05" "2011" "07" "32" "40"
    Date_Time.1 "19" "05" "2011" "13" "26" "02"
    Date_Time.2 "19" "05" "2011" "13" "32" "47"
    Date_Time.3 "19" "05" "2011" "13" "45" "24"
    Date_Time.4 "19" "05" "2011" "14" "57" "27"
    Date_Time.5 "19" "05" "2011" "15" "03" "18"
    

    以防万一您想将它们全部转换为数字。

    apply(my.data2, 2, function(x) as.numeric(as.character(x)))
    

    【讨论】:

    • 不错的解决方案。我认为您也可以在最后一步避免as.character,因为x 已经是一个字符
    • @VeerendraGadekar 我知道你是对的,但我不记得我在哪里看到了对该代码的解释以及最好这样做的原因,或者可能只是因为我这样做不记得。有疑问,我保留了该代码。
    【解决方案3】:

    使用cSplit

    library(splitstackshape)
    tmp = cSplit(my.data, "Date_Time", "/")
    out = cSplit(tmp, "Date_Time_3", ":")
    

    如果你像这样阅读你的数据

    my.data <- read.csv(text = 'Date Time
    18/05/2011 07:32:40
    19/05/2011 13:26:02
    19/05/2011 13:32:47
    19/05/2011 13:45:24
    19/05/2011 14:57:27
    19/05/2011 15:03:18', header=TRUE, sep =' ' ,stringsAsFactors = FALSE, na.strings = 'NA', strip.white = TRUE)
    

    你可以的

    library(splitstackshape)
    out = cSplit(my.data, splitCols = c("Date", "Time"), sep = c("/", ":"))
    
    #> out
    #   Date_1 Date_2 Date_3 Time_1 Time_2 Time_3
    #1:     18      5   2011      7     32     40
    #2:     19      5   2011     13     26      2
    #3:     19      5   2011     13     32     47
    #4:     19      5   2011     13     45     24
    #5:     19      5   2011     14     57     27
    #6:     19      5   2011     15      3     18
    

    【讨论】:

      【解决方案4】:

      您可以考虑为此使用 gsubfn 包中的 read.pattern

      library(gsubfn)
      read.pattern(text = my.data$Date_Time, pattern = "\\d+")
      
      #   V1 V2   V3 V4 V5 V6
      # 1 18  5 2011  7 32 40
      # 2 19  5 2011 13 26  2
      # 3 19  5 2011 13 32 47
      # 4 19  5 2011 13 45 24
      # 5 19  5 2011 14 57 27
      # 6 19  5 2011 15  3 18
      

      然后您可以根据需要简单地分配列名。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-13
        • 1970-01-01
        • 2012-11-12
        • 2022-06-15
        • 2016-03-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多