Как преобразовать список в датафрейм без преобразования типа по дате - PullRequest
0 голосов
/ 03 июня 2018

Я пытаюсь написать скрипт, который может принимать файл, искать некоторые метаданные, относящиеся к файлу, и конвертировать определенные столбцы на основе этих метаданных.Например, предположим, что мои данные выглядят как вывод следующего:

test_data <- data.frame(date1 = c("03/02/2018","04/25/2018"),date2 = c("9/14/17","9/27/17"))

и предположим, что на основе поиска метаданных я обнаружил, что столбцы date1 и date2 входного файла имеют,соответственно, форматы

date_formats <- c("%m/%d/%Y","%m/%d/%y")

Таким образом, мой сценарий затем продолжит определять index как логический вектор, который содержит значение TRUE, где у меня есть столбец даты и FALSE в противном случае, и затем попытаетсяЧтобы преобразовать все такие столбцы в стандартизированный формат даты R:

test_data[,index] <- as.data.frame( 
                     lapply(test_data[,index],as.Date,
                     format = date_formats[index],
                               origin ="1970-01-01")))

Но это приводит к некоторому странному выводу:

  date1      date2
1 2018-03-02 0017-09-14
2 2020-04-25 2017-09-27

Обратите внимание, что годы для (1,2) и (2,1) записи выключены.Я не понимаю, почему другие значения были правильно преобразованы.Это загадка №1.

Другая загадка заключается в том, что если я попытаюсь преобразовать только один столбец, скажем

as.data.frame(lapply(test_data[,1],as.Date,format = c("%m/%d/%Y")))

, то получу нежелательный вывод:

structure.17592..class....Date.. structure.17646..class....Date..
1                       2018-03-02                       2018-04-25

и если я сначала оберну это с cbind а-ля

as.data.frame( cbind(lapply(test_data[,1],as.Date,format = c("%m/%d/%Y"))))

, то получу необработанные неформатированные значения даты из-за поведения cbind:

    V1
1 17592
2 17646

Итак, как я могу написать этот универсальный метод, который может обрабатывать произвольное количество столбцов в разных форматах и ​​преобразовывать их все в один форматированный тип даты в кадре данных?

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

Похоже, что целью OP является чтение данных из файла, некоторые столбцы которого содержат дату в разных форматах.@Moody_Mudskipper уже предоставил хорошее решение для преобразования данных после их чтения из файла.

Другой вариант - использовать аргумент colClasses функций чтения (например, read.table, read.csv и т. Д.) И преобразовать столбцы даты.

# Test data to be read from file. I have added one more column ID in data from OP
textData <- "
ID       date1   date2
1 03/02/2018 9/14/17
2 04/25/2018 9/27/17"

setClass("dateformat1")
setClass("dateformat2")

setAs("character", "dateformat1", function(from)as.Date(from, format = "%m/%d/%Y"))
setAs("character", "dateformat2", function(from)as.Date(from, format = "%m/%d/%y"))


read.table(text = textData, header = TRUE, stringsAsFactors = FALSE, 
           colClasses = c("numeric", "dateformat1","dateformat2"))

#   ID      date1      date2
# 1  1 2018-03-02 2017-09-14
# 2  2 2018-04-25 2017-09-27
0 голосов
/ 03 июня 2018

Попробуйте это:

test_data <- data.frame(date1 = c("03/02/2018","04/25/2018"),date2 = c("9/14/17","9/27/17"))
date_formats <- c("%m/%d/%Y","%m/%d/%y")
index <- c(TRUE,TRUE)

test_data[,index] <- 
  as.data.frame( 
    lapply(which(index),function(i) 
      as.Date(test_data[[i]],
              format = date_formats[i],
              origin ="1970-01-01")))

#        date1      date2
# 1 2018-03-02 2017-09-14
# 2 2018-04-25 2017-09-27

index, который вы подавали на date_formats в вашем цикле lapply, всегда был длиной 2, lapply не зацикливался на нем.Нам нужно преобразовать ваш логический индекс в числовой, а затем зациклить его.

Вот более чистый код для достижения желаемого:

test_data[,index] <- 
  Map(as.Date,test_data[index],date_formats[index],origin ="1970-01-01")
#        date1      date2
# 1 2018-03-02 2017-09-14
# 2 2018-04-25 2017-09-27
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...