Yıl ve ayı ("yyyy-aa" biçimi) tarihe mi çeviriyorsunuz?


91

Şuna benzeyen bir veri kümem var:

Month    count
2009-01  12
2009-02  310
2009-03  2379
2009-04  234
2009-05  14
2009-08  1
2009-09  34
2009-10  2386

Verileri çizmek istiyorum (aylar x değerleri olarak ve y değerleri olarak sayılır). Verilerde boşluklar olduğu için, Ayın Bilgisini bir tarihe dönüştürmek istiyorum. Denedim:

as.Date("2009-03", "%Y-%m")

Ama çalışmadı. Sorun nedir? Görünüşe göre as.Date () ayrıca bir gün gerektiriyor ve gün için standart bir değer ayarlayamıyor mu? Hangi işlev sorunumu çözer?

Yanıtlar:


57

Bunu dene. (Burada text=Linesörneği kendi içinde tutmak için kullanıyoruz , ancak gerçekte onu dosya adıyla değiştirirdik.)

Lines <- "2009-01  12
2009-02  310
2009-03  2379
2009-04  234
2009-05  14
2009-08  1
2009-09  34
2009-10  2386"

library(zoo)
z <- read.zoo(text = Lines, FUN = as.yearmon)
plot(z)

X ekseni bu verilerle o kadar güzel değil, ancak gerçekte daha fazla veriye sahipseniz, sorun olmayabilir veya örnekler bölümünde gösterilen şık bir X ekseni için kodu kullanabilirsiniz ?plot.zoo.

zYukarıda oluşturulan hayvanat bahçesi serisinin bir "yearmon"zaman indeksi vardır ve şuna benzer:

> z
Jan 2009 Feb 2009 Mar 2009 Apr 2009 May 2009 Aug 2009 Sep 2009 Oct 2009 
      12      310     2379      234       14        1       34     2386 

"yearmon" tek başına da kullanılabilir:

> as.yearmon("2000-03")
[1] "Mar 2000"

Not:

  1. "yearmon" sınıf nesneleri takvim sırasına göre sıralanır.

  2. Bu, aylık noktaları eşit aralıklarla çizecektir, ki bu muhtemelen istenen şeydir; her ayın gün sayısına orantılı olarak aralıklı eşit olmayan aralıklı aralıklarla noktalar çizmek için arzu olsaydı ancak o zaman dizinini dönüştürmek ziçin "Date"sınıfa: time(z) <- as.Date(time(z)).


76

Tarihler sayısal bir değere ve bir başlangıç ​​tarihine karşılık geldiğinden, gerçekten güne ihtiyacınız vardır. Verilerinizin Tarih biçiminde olmasına gerçekten ihtiyacınız varsa, tarihi manuel olarak her ayın ilkine yapıştırarak günü düzeltebilirsiniz:

month <- "2009-03"
as.Date(paste(month,"-01",sep=""))

Tarihler için başka hangi formatlar var? POSIX ile bir şey ve ISO ile bir şey gördüm, ancak bunların farklı formatlar olup olmadığından emin değilim. Bunların sadece işlevler olduğunu düşünmüştüm, ...
R_User

19
Biçimlendiricide günü aynı olarak belirleyebileceğinizi, böylece as.Date(month, format='%Y-%m-01')aynı sonucu yapabilir ve elde edebilirsiniz . Her ay aynı tarihi belirtmek daha çok tarih biçimi ve daha sonra dize manipülasyonu ile ilgili olduğu için bu bana "tercih edilir" geliyor, ama belki de bu saçma.
JBecker

21
@JBecker öneriniz benim için çalışmıyor. > as.Date("2016-01", format="%Y-%m-01") # [1] NA. R 3.3.1
n8sty

26

Tarihlerin Tarih biçiminde olması gerekiyorsa en kısa çözüm:

library(zoo)
month <- "2000-03"
as.Date(as.yearmon(month))
[1] "2000-03-01"

as.Date her ayın ilk gününü sizin için bir yıllık nesneye düzeltir.


23

Bunu , -package'deki parse_date_timeveya fast_strptimeişlevleriyle de elde edebilirsiniz lubridate:

> parse_date_time(dates1, "ym")
[1] "2009-01-01 UTC" "2009-02-01 UTC" "2009-03-01 UTC"

> fast_strptime(dates1, "%Y-%m")
[1] "2009-01-01 UTC" "2009-02-01 UTC" "2009-03-01 UTC"

Bu ikisi arasındaki fark parse_date_time, lubridate-style format spesifikasyonuna izin verirken fast_strptime, aynı format spesifikasyonunu gerektirir strptime.

tzSaat dilimini belirtmek için -parametresini kullanabilirsiniz :

> parse_date_time(dates1, "ym", tz = "CET")
[1] "2009-01-01 CET" "2009-02-01 CET" "2009-03-01 CET"

Tarih-saat verilerinizde truncateddüzensizlikler olduğunda, kaç düzensizliğe izin verildiğini belirtmek için -parametresini kullanabilirsiniz :

> parse_date_time(dates2, "ymdHMS", truncated = 3)
[1] "2012-06-01 12:23:00 UTC" "2012-06-01 12:00:00 UTC" "2012-06-01 00:00:00 UTC"

Kullanılan veriler:

dates1 <- c("2009-01","2009-02","2009-03")
dates2 <- c("2012-06-01 12:23","2012-06-01 12",'2012-06-01")

datekullanarak bir karakter değişkenini formata dönüştürdükten sonra parse_date_time, onu paket "2009-01-01 UTC"kullanmaktan farklı bir sırada görüntülemenin bir yolu var lubridatemı? Veri setimde ilk günü görmeyi tercih ederim örn 01-01-2009.
user63230

1
@ user63230 Bkz ?format; örneğin: format(your_date, "%d-%m-%Y"). Yine de bunun bir dezavantajı var: bir tarih değil, bir karakter değerini geri alacaksınız.
Jaap

Teşekkürler ama formatbahsettiğiniz nedenle kaçınmaya çalışıyordum , bunu lubridatepakete dahil etmenin bir yolu olabileceğini düşündüm ama yok gibi görünüyor.
user63230

12

Her zaman paketi kullanma :

library(anytime)

anydate("2009-01")
# [1] "2009-01-01"

"01-01" i seçmesi biraz garip, belgelerde seçimle ilgili herhangi bir şey var mı? Belki anydate("2009-03")her zaman ayın ilk gününü seçip seçmediğini göstermek için daha açıklayıcı olabilir .
lmo

@lmo dokümanları kontrol etmedi, dd 1. günü seçmek için eksik olduğunda bunun "yaygın" bir uygulama olduğunu söyleyebilirim.
zx8754

2
Mantıklı. Belirsiz bir şekilde hatırlandım ve sonra yorumu tetikleyen şeyi buldum. Not bölümünden ?strptime: giriş dizesinin tarihi tam olarak belirtmesi gerekmez: belirtilmemiş saniye, dakika veya saatlerin sıfır olduğu ve belirtilmemiş bir yıl, ay veya günün geçerli olduğu varsayılır. (Bununla birlikte, bir ay belirtilmişse, o ayın gününün% d veya% e ile belirtilmesi gerekir çünkü ayın mevcut gününün belirtilen ay için geçerli olması gerekmez.) Megatron'un cevabı benzer bir parça içeriyor gibi görünüyor gelen belgelerin as.Date.
lmo

1900'den önceki yıllar için işe yaramıyor. Örneğin, bunu denedimanytime('1870-01')
msh855

5

Aslında, yukarıda (ve SO'da başka yerlerde) belirtildiği gibi, dizeyi bir tarihe dönüştürmek için ayın belirli bir tarihine ihtiyacınız vardır. Gönderen as.Date()manuel sayfa:

Tarih dizesi tarihi tam olarak belirtmiyorsa, döndürülen yanıt sisteme özgü olabilir. En yaygın davranış, eksik yıl, ay veya günün mevcut olan olduğunu varsaymaktır. Bir tarihi yanlış belirtirse, güvenilir uygulamalar hata verir ve tarih NA olarak bildirilir. Ne yazık ki bazı yaygın uygulamalar (gibi glibc) güvenilmezdir ve amaçlanan anlamı tahmin eder.

Basit bir çözüm, tarihi "01"her tarihe yapıştırmak ve strptime()bunu o ayın ilk günü olarak belirtmek olabilir.


R'de tarih ve saatleri işleme konusunda biraz daha fazla bilgi arayanlar için:

R'de, zamanlar kullanılır POSIXctve POSIXltsınıflar ve tarihler Datesınıfı kullanır .

Tarihler, 1 Ocak 1970'den itibaren gün sayısı olarak saklanır ve zamanlar, 1 Ocak 1970'ten itibaren saniye sayısı olarak saklanır.

Yani mesela:

d <- as.Date("1971-01-01")
unclass(d)  # one year after 1970-01-01
# [1] 365

pct <- Sys.time()  # in POSIXct
unclass(pct)  # number of seconds since 1970-01-01
# [1] 1450276559
plt <- as.POSIXlt(pct)
up <- unclass(plt)  # up is now a list containing the components of time
names(up)
# [1] "sec"    "min"    "hour"   "mday"   "mon"    "year"   "wday"   "yday"   "isdst"  "zone"  
# [11] "gmtoff"
up$hour
# [1] 9

Tarih ve saatlerde işlem yapmak için:

plt - as.POSIXlt(d)
# Time difference of 16420.61 days

Tarihleri ​​işlemek için şunları kullanabilirsiniz strptime()(bu örnekleri kılavuz sayfasından ödünç alarak):

strptime("20/2/06 11:16:16.683", "%d/%m/%y %H:%M:%OS")
# [1] "2006-02-20 11:16:16 EST"

# And in vectorized form:
dates <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960")
strptime(dates, "%d%b%Y")
# [1] "1960-01-01 EST" "1960-01-02 EST" "1960-03-31 EST" "1960-07-30 EDT"

1

@ Ben-rollert'in çözümünün iyi bir çözüm olduğunu düşünüyorum.

Bu çözümü yeni bir paketin içindeki bir işlevde kullanmak istiyorsanız dikkatli olmalısınız.

Paketleri Gelişen zaman, Syntaxe kullanılmasını öneriyoruz packagename::function_name()(bkz http://kbroman.org/pkg_primer/pages/depends.html ).

Bu durumda, kütüphane as.Date()tarafından tanımlanan versiyonu kullanmanız gerekir zoo.

İşte bir örnek :

> devtools::session_info()
Session info ----------------------------------------------------------------------------------------------------------------------------------------------------
 setting  value                       
 version  R version 3.3.1 (2016-06-21)
 system   x86_64, linux-gnu           
 ui       RStudio (1.0.35)            
 language (EN)                        
 collate  C                           
 tz       <NA>                        
 date     2016-11-09                  

Packages --------------------------------------------------------------------------------------------------------------------------------------------------------

 package  * version date       source        
 devtools   1.12.0  2016-06-24 CRAN (R 3.3.1)
 digest     0.6.10  2016-08-02 CRAN (R 3.2.3)
 memoise    1.0.0   2016-01-29 CRAN (R 3.2.3)
 withr      1.0.2   2016-06-20 CRAN (R 3.2.3)

> as.Date(zoo::as.yearmon("1989-10", "%Y-%m")) 
Error in as.Date.default(zoo::as.yearmon("1989-10", "%Y-%m")) : 
  do not know how to convert 'zoo::as.yearmon("1989-10", "%Y-%m")' to class “Date”

> zoo::as.Date(zoo::as.yearmon("1989-10", "%Y-%m"))
[1] "1989-10-01"

Dolayısıyla, bir paket geliştiriyorsanız, iyi uygulama şunları kullanmaktır:

zoo::as.Date(zoo::as.yearmon("1989-10", "%Y-%m"))
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.