R, несовместимый формат даты - PullRequest
0 голосов
/ 09 мая 2020

У меня есть переменная даты, изначально взятая из Excel. Однако он настолько неоднороден. Несмотря на то, что в Excel все выглядит как yyyy / mm / dd, при чтении в R переменная выглядит так:

person_1  39257
person_2  2015/2/20
person_3  NA

Как очистить переменную даты, чтобы каждый показывал yyyy / mm / формат dd?

Ответы [ 3 ]

3 голосов
/ 09 мая 2020

Или вариант с anydate и excel_numeric_to_date

library(janitor)
library(anytime)
library(dplyr)
coalesce( excel_numeric_to_date(as.numeric(dat$V2)), anydate(dat$V2))
#[1] "2007-06-24" "2015-02-20" NA   

данные

dat <- structure(list(V1 = c("person_1", "person_2", "person_3"), V2 = c("39257", 
"2015/2/20", NA)), class = "data.frame", row.names = c(NA, -3L
))
2 голосов
/ 09 мая 2020

Итеративный подход, аналогичный тому, как пакеты вроде lubridate и другие пытаются найти совпадение. Здесь используется несколько, включая модель Excel (которая, я думаю, использует происхождение «1900-01-01», кстати). Порядок немного важен: перед лицом двусмысленности лучший эвристический c найдет тот, у которого больше всего совпадений, и использует его для всех ... но это уже ваше дело.

dat <- read.table(header=FALSE, stringsAsFactors=FALSE, text="
person_1  39257
person_2  2015/2/20
person_3  NA")

conv_dates <- function(dates, origin = "1900-01-01") {
  out <- Sys.Date()[rep(NA, length(dates))]
  notna0 <- !is.na(dates)
  allnum <- notna0 & grepl("^[.0-9]+$", dates)
  if (any(allnum)) out[allnum] <- suppressWarnings(as.Date(as.numeric(dates[allnum]), origin = origin))
  fmts <- c("%Y/%m/%d", "%d/%m/%Y", "%m/%d/%Y")
  for (fmt in fmts) {
    isna <- notna0 & is.na(out)
    if (!any(isna)) break
    out[isna] <- as.Date(dates[isna], format = fmt)
  }
  out
}

str(conv_dates(dat$V2))
#  Date[1:3], format: "2007-06-26" "2015-02-20" NA
0 голосов
/ 09 мая 2020

Вы можете сначала изменить даты, используя их соответствующий формат в YMD, а затем изменить дату c excel с их происхождением.

dat$date <- as.Date(dat$V2, '%Y/%m/%d')
#Can also use
#dat$V2 <- lubridate::ymd(dat$V2)
inds <- is.na(dat$date)
dat$date[inds] <- as.Date(as.numeric(dat$V2[inds]),origin = "1899-12-30")
dat

#        V1        V2       date
#1 person_1     39257 2007-06-24
#2 person_2 2015/2/20 2015-02-20
#3 person_3      <NA>       <NA>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...