我有一个数据框,其中日期存储为double
,例如1993.09 1993.10 1993.11 1993.12
我想将其转换为日期格式'%Y %m %d'
(日期始终为1
)。
据我了解,as.Date()
想要一个字符串输入。但是,由于某种原因,当我将日期转换为字符串sapply(dates, as.character)
时,零之后的零点消失,有效地将10月转换为1月,从而导致每年两个日期。
dates
1993.07 1993.08 1993.09 1993.10 1993.11 1993.12
sapply(dates, as.character)
sub("[.]", " ", dates)
"1993 07" "1993 08" "1993 09" "1993 1" "1993 11" "1993 12"
是否有更直接的方式来转换日期?或者我在哪里陷入困境?
dput:
c(1993.01, 1993.02, 1993.03, 1993.04, 1993.05, 1993.06, 1993.07,
1993.08, 1993.09, 1993.1, 1993.11, 1993.12)
答案 0 :(得分:9)
你的问题是你有一些字符串,但看起来像数字,你在导入过程中没有注意这一点。 R不区分1993.1
和1993.10
。两者都是相同的数字。因此,as.character(1993.10)
会返回"1993.1"
。您需要使用格式化功能,以确保在句点之后得到两位数,因为as.Date
"1993.1"
和"1993.01"
是同一个月。
x <- c(1993.09, 1993.10, 1993.11, 1993.12)
as.Date(sprintf("%.2f.01", x), format = "%Y.%m.%d")
#[1] "1993-09-01" "1993-10-01" "1993-11-01" "1993-12-01"
当然,x
应该作为角色导入。
答案 1 :(得分:6)
如果您确实只是想在本月的第一天将其转换为"Date"
级别,那么Roland的解决方案似乎最直接,但还有一些其他考虑因素,例如您是否可能想要使用月末或是否真的想用年份来表示使用日期的年月。
zoo包有一个"yearmon"
类,可以直接表示年月而不将它们转换为日期,并且as.Date.yearmon
方法可以使用frac=
参数来指定如果你想要"Date"
类,那么转换为月份的路段的一小部分。
首先,确保日期是字符串。问题中的输入显示为1993.10作为输入之一,因此我们必须确保有一个尾随零。 (如果输入已经是尾随零的字符,那么这不是问题。我们假设这里最坏的情况假定为数字,因此我们需要显式地将它们转换为字符串,如果需要,则尾随0。)现在使用{格式为as.yearmon
的{1}}。最后使用"%Y.%m"
转换为as.Date.yearmon
类。
这种方法的最大优点可能是我们可以将结果保留在"Date"
类中(即省略"yearmon"
部分,例如"as.Date"
或者日期是否已经是字符串,as.yearmon(sprintf("%.2f", dates))
,在dates.ch
然后只有"1993.10"
的情况下尾随0,这实际上代表了你自那天以来更好的东西并不是真正有意义的,因为它不在那里开始。as.yearmon(dates.ch, "%Y.%m")
对象可以按照预期的方式进行绘制和排序。
以下是使用"yearmon"
转换为"Date"
课程:
"yearmon"
或者测试输入是这样的:
library(zoo)
dates <- c(1993.07, 1993.08, 1993.09, 1993.1, 1993.11, 1993.12) # test input
as.Date(as.yearmon(sprintf("%.2f", dates), "%Y.%m")) # 1st of month
## [1] "1993-07-01" "1993-08-01" "1993-09-01" "1993-10-01" "1993-11-01" "1993-12-01"
as.Date(as.yearmon(sprintf("%.2f", dates), "%Y.%m"), frac = 1) # last of month
## [1] "1993-07-31" "1993-08-31" "1993-09-30" "1993-10-31" "1993-11-30" "1993-12-31"
答案 2 :(得分:2)
使用paste0
添加日期并从?strptime
查找日期格式的值。如果您在使用双字符串格式时遇到问题,可以使用formatC
:
txtfield <- c(1993.01, 1993.02, 1993.03, 1993.04, 1993.05, 1993.06, 1993.07,
1993.08, 1993.09, 1993.1, 1993.11, 1993.12)
as.Date(paste0(formatC(txtfield, digits=2, format="f"),".01"), "%Y.%m.%d")
说明:
paste0
是paste
的简写版本,不会在粘贴的元素之间插入空格。
在formatC
中,digits
指定小数点后所需的位数(在我们的例子中我们想要2.格式告诉R使用哪个数字格式,在我们的例子中“f”给出数字数字以所需的xxx.xxx格式。
as.Date
转换为原生R日期格式,“%Y。%m。%d”指定全年(4位)后跟一个点,后跟数字月(2位)后跟一个点,其次是数字日。
结果:
[1] "1993-01-01" "1993-02-01" "1993-03-01" "1993-04-01" "1993-05-01" "1993-06-01"
[7] "1993-07-01" "1993-08-01" "1993-09-01" "1993-10-01" "1993-11-01" "1993-12-01"
答案 3 :(得分:0)
你需要做一些摆弄字符串。最明显的方式(对我来说)是用零填充值的右侧。
*
这是一个非常重要的警告
dates <- c(1993.01, 1993.02, 1993.03, 1993.04, 1993.05, 1993.06, 1993.07,
1993.08, 1993.09, 1993.10, 1993.11, 1993.12)
library(magrittr)
library(stringr)
dates %<>%
str_pad(width = 7, side = "right", pad = "0") %>%
paste0(".01") %>%
as.Date(format = "%Y.%m.%d")
dates