Read.table / read.csv dosyasında colClasses bağımsız değişkeni için özel Tarih biçimini belirtin


101

Soru:

Read.table / read.csv dosyasında colClasses bağımsız değişkenini kullanırken Tarih biçimini belirtmenin bir yolu var mı?

(İçe aktardıktan sonra dönüştürebileceğimi biliyorum, ancak bunun gibi birçok tarih sütununda bunu içe aktarma adımında yapmak daha kolay olurdu)


Misal:

Tarih sütunları biçiminde bir .csv dosyam var %d/%m/%Y.

dataImport <- read.csv("data.csv", colClasses = c("factor","factor","Date"))

Bu, dönüşümü yanlış yapar. Örneğin, 15/07/2008olur 0015-07-20.


Tekrarlanabilir kod:

data <- 
structure(list(func_loc = structure(c(1L, 2L, 3L, 3L, 3L, 3L, 
3L, 4L, 4L, 5L), .Label = c("3076WAG0003", "3076WAG0004", "3076WAG0007", 
"3076WAG0009", "3076WAG0010"), class = "factor"), order_type = structure(c(3L, 
3L, 1L, 1L, 1L, 1L, 2L, 2L, 3L, 1L), .Label = c("PM01", "PM02", 
"PM03"), class = "factor"), actual_finish = structure(c(4L, 6L, 
1L, 2L, 3L, 7L, 1L, 8L, 1L, 5L), .Label = c("", "11/03/2008", 
"14/08/2008", "15/07/2008", "17/03/2008", "19/01/2009", "22/09/2008", 
"6/09/2007"), class = "factor")), .Names = c("func_loc", "order_type", 
"actual_finish"), row.names = c(NA, 10L), class = "data.frame")


write.csv(data,"data.csv", row.names = F)                                                        

dataImport <- read.csv("data.csv")
str(dataImport)
dataImport

dataImport <- read.csv("data.csv", colClasses = c("factor","factor","Date"))
str(dataImport)
dataImport

Ve çıktı şu şekilde görünüyor:

kod çıkışı


Bunu yapmanın hilekâr bir yolu, kendi versiyonunuzu yaratmak read.tableve formatona aktarılan bir argüman eklemek olacaktır as.Date. Yine de düşünmediğim daha iyi bir yol olsa şaşırmam.
joran

Yanıtlar:


158

Bir dizeyi kabul eden ve bunu istediğiniz biçimi kullanarak Tarihe dönüştüren kendi işlevinizi yazabilir, ardından yöntem setAsolarak ayarlamak için işlevini kullanabilirsiniz as. Ardından, işlevinizi sınıf sınıflarının bir parçası olarak kullanabilirsiniz.

Deneyin:

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

tmp <- c("1, 15/08/2008", "2, 23/05/2010")
con <- textConnection(tmp)

tmp2 <- read.csv(con, colClasses=c('numeric','myDate'), header=FALSE)
str(tmp2)

Ardından, verileriniz için çalışmak üzere gerekirse değiştirin.

Düzenle ---

Uyarıdan setClass('myDate')kaçınmak için önce koşmak isteyebilirsiniz (uyarıyı görmezden gelebilirsiniz, ancak bunu çok yaparsanız can sıkıcı olabilir ve bu, ondan kurtulan basit bir çağrıdır).


2
Vay be - setAs bir cankurtaran! Bu işlevi daha önce nasıl görmedim?
user295691

4
Bu soruda ayrıntılı olarak belirtildiği gibi "" myDate "sınıfı için tanım yok" uyarısı alabileceğinizi unutmayın .
Danny D'Amours

1
Ne setMethod('myDate')yapmalı? Çalıştırmak bana bir hata veriyor ...
Josh O'Brien

1
@ JoshO'Brien, özür dilerim setClass(şimdi düzeltildi). setAsYaptığı şey, sınıf olarak mevcut olmayan 'myDate' hakkında bir uyarı vermesini engellemektir . Uyarı zararsızdır ve her şey hala çalışır, ancak sınıfı belirlemek, uyarıyı bile görmediğiniz anlamına gelir.
Greg Snow

1
@MySchizoBuddy, Yalnızca bir tarih sütununuz varsa ve bunu bir kez yapıyorsanız, büyük olasılıkla hangi şekilde yaptığınız önemli değildir. Ancak veri kümenizde tarih olan birkaç sütun varsa, bu yaklaşımın okuduktan sonra her bir sütunu değiştirmekten daha kolay olacağını düşünüyorum.
Greg Snow

25

Değiştirmek istediğiniz yalnızca 1 tarih formatı varsa Defaults, varsayılan formatı içinde değiştirmek için paketi kullanabilirsiniz.as.Date.character

library(Defaults)
setDefaults('as.Date.character', format = '%d/%M/%Y')
dataImport <- read.csv("data.csv", colClasses = c("factor","factor","Date"))
str(dataImport)
## 'data.frame':    10 obs. of  3 variables:
##  $ func_loc     : Factor w/ 5 levels "3076WAG0003",..: 1 2 3 3 3 3 3 4 4 5
##  $ order_type   : Factor w/ 3 levels "PM01","PM02",..: 3 3 1 1 1 1 2 2 3 1
##  $ actual_finish: Date, format: "2008-10-15" "2009-10-19" NA "2008-10-11" ...

Sık kullanılan bir işlevin varsayılan davranışını değiştirmediği için @Greg Snow'un cevabının çok daha iyi olduğunu düşünüyorum.


7

Ayrıca zamana ihtiyacınız olursa:

setClass('yyyymmdd-hhmmss')
setAs("character","yyyymmdd-hhmmss", function(from) as.POSIXct(from, format="%Y%m%d-%H%M%S"))
d <- read.table(colClasses="yyyymmdd-hhmmss", text="20150711-130153")
str(d)
## 'data.frame':    1 obs. of  1 variable:
## $ V1: POSIXct, format: "2015-07-11 13:01:53"

2

Uzun zaman önce, bu arada sorun Hadley Wickham tarafından çözüldü. Dolayısıyla günümüzde çözüm tek bir çizgiye indirgenmiştir:

library(readr)
data <- read_csv("data.csv", 
                  col_types = cols(actual_finish = col_datetime(format = "%d/%m/%Y")))

Belki gereksiz şeylerden kurtulmak bile istiyoruz:

data <- as.data.frame(data)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.