【问题标题】:Convert string to date, format: "dd.mm.yyyy"将字符串转换为日期,格式:“dd.mm.yyyy”
【发布时间】:2012-01-13 22:47:56
【问题描述】:
D <- "06.12.1948"                 # which is dd.mm.yyyy
as.Date(D, "%d.%m.%y")            # convert to date
[1] "2019-12-06"                  # ????    

我错过了什么?

Sys.getlocale(category = "LC_ALL") [1] "LC_COLLATE=German_Austria.1252;LC_CTYPE=German_Austria.1252;LC_MONETARY=German_Austria.1252;LC_NUMERIC=C;LC_TIME=German_Austria.1252"

【问题讨论】:

    标签: r date


    【解决方案1】:

    格式区分大小写(我相信“%y”有歧义且取决于系统):

    as.Date(D, "%d.%m.%Y")
    [1] "1948-12-06"
    

    帮助主题?strptime有详细说明:

     ‘%y’ Year without century (00-99).  On input, values 00 to 68 are
          prefixed by 20 and 69 to 99 by 19 - that is the behaviour
          specified by the 2004 and 2008 POSIX standards, but they do
          also say ‘it is expected that in a future version the default
          century inferred from a 2-digit year will change’.
    

    【讨论】:

    • 为了扩展这一点,"%y" 是两位数的年份,所以它在 1948 年的“19”中读取。你想要"%Y"
    【解决方案2】:

    为避免记住日期格式,我们可以使用打包解决方案。

    1) 与lubridate

    lubridate::dmy(D)
    #[1] "1948-12-06"
    

    2) 使用anytime

    anytime::anydate(D)
    #[1] "1948-06-12"
    

    【讨论】:

      【解决方案3】:

      可能对某人有帮助。我在 Cole Beck 的教程“在 R 中处理日期时间”中找到了这个函数。该函数识别数据的格式。

      # FUNCTION guessDateFormat @x vector of character dates/datetimes @returnDates return
      # actual dates rather than format convert character datetime to POSIXlt datetime, or 
      # at least guess the format such that you could convert to datetime
      guessDateFormat <- function(x, returnDates = FALSE, tzone = "") {
      x1 <- x
      # replace blanks with NA and remove
      x1[x1 == ""] <- NA
      x1 <- x1[!is.na(x1)]
      if (length(x1) == 0)
        return(NA)
      # if it's already a time variable, set it to character
      if ("POSIXt" %in% class(x1[1])) {
      x1 <- as.character(x1)
      }
      dateTimes <- do.call(rbind, strsplit(x1, " "))
      for (i in ncol(dateTimes)) {
      dateTimes[dateTimes[, i] == "NA"] <- NA
      }
      # assume the time part can be found with a colon
      timePart <- which(apply(dateTimes, MARGIN = 2, FUN = function(i) {
                              any(grepl(":", i))
                              }))
      # everything not in the timePart should be in the datePart
      datePart <- setdiff(seq(ncol(dateTimes)), timePart)
      # should have 0 or 1 timeParts and exactly one dateParts
      if (length(timePart) > 1 || length(datePart) != 1)
        stop("cannot parse your time variable")
      timeFormat <- NA
      if (length(timePart)) {
      # find maximum number of colons in the timePart column
      ncolons <- max(nchar(gsub("[^:]", "", na.omit(dateTimes[, timePart]))))
      if (ncolons == 1) {
      timeFormat <- "%H:%M"
      } else if (ncolons == 2) {
      timeFormat <- "%H:%M:%S"
      } else stop("timePart should have 1 or 2 colons")
      }
      # remove all non-numeric values
      dates <- gsub("[^0-9]", "", na.omit(dateTimes[, datePart]))
      # sep is any non-numeric value found, hopefully / or -
      sep <- unique(na.omit(substr(gsub("[0-9]", "", dateTimes[, datePart]), 1, 1)))
      if (length(sep) > 1)
        stop("too many seperators in datePart")
      # maximum number of characters found in the date part
      dlen <- max(nchar(dates))
      dateFormat <- NA
      # when six, expect the century to be omitted
      if (dlen == 6) {
      if (sum(is.na(as.Date(dates, format = "%y%m%d"))) == 0) {
      dateFormat <- paste("%y", "%m", "%d", sep = sep)
      } else if (sum(is.na(as.Date(dates, format = "%m%d%y"))) == 0) {
      dateFormat <- paste("%m", "%d", "%y", sep = sep)
      } else stop("datePart format [six characters] is inconsistent")
      }else if (dlen == 8) {
      if (sum(is.na(as.Date(dates, format = "%Y%m%d"))) == 0) {
      dateFormat <- paste("%Y", "%m", "%d", sep = sep)
      } else if (sum(is.na(as.Date(dates, format = "%m%d%Y"))) == 0) {
      dateFormat <- paste("%m", "%d", "%Y", sep = sep)
      } else stop("datePart format [eight characters] is inconsistent")
      } else {
      stop(sprintf("datePart has unusual length: %s", dlen))
      }
      if (is.na(timeFormat)) {
      format <- dateFormat
      } else if (timePart == 1) {
      format <- paste(timeFormat, dateFormat)
      } else if (timePart == 2) {
      format <- paste(dateFormat, timeFormat)
      } else stop("cannot parse your time variable")
      if (returnDates)
        return(as.POSIXlt(x, format = format, tz = tzone))
      format
      }
      
      # generate some dates
      mydates <- format(as.POSIXct(sample(31536000, 20), origin = "2011-01-01", tz = "UTC"), "%m.%d.%Y %H:%M")
      
      mydates
      ## [1] "02/07/2011 06:51" "11/21/2011 17:03" "09/17/2011 22:42" "02/16/2011 13:45"
      ## [5] "12/14/2011 19:11" "09/08/2011 09:22" "12/06/2011 14:06" "02/02/2011 11:00"
      ## [9] "03/27/2011 06:12" "01/05/2011 15:09" "04/15/2011 04:17" "10/20/2011 14:20"
      ## [13] "11/13/2011 21:46" "02/26/2011 03:24" "12/29/2011 11:02" "03/17/2011 02:24"
      ## [17] "02/27/2011 13:51" "06/27/2011 08:36" "03/14/2011 10:54" "01/28/2011 14:14"
      guessDateFormat(mydates)
      

      [1] "%m.%d.%Y %H:%M"

      【讨论】:

        【解决方案4】:

        在我看来,Lubridate 是最好的选择。以下将正常工作。

        `data %>% mutate(date_variable = as.Date(dmy(date_variable)))`
        

        有趣的是,虽然我发现 dmy() 在 as.Date() 和 dmy() 被分别调用时表现得很奇怪

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-16
          • 1970-01-01
          • 2014-07-29
          • 2013-12-28
          • 1970-01-01
          • 2014-01-18
          相关资源
          最近更新 更多