7

I have a data frame where date is stored as a double e.g., 1993.09 1993.10 1993.11 1993.12

I want to convert this into a date format '%Y %m %d' (with days always 1).

As far as I understand, as.Date() wants a string input. However, for some reason when I convert my dates into string sapply(dates, as.character) the zeros after ones disappear, effectively converting October to January, resulting into two Januaries per year.

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"

Is there a more straightforward way of converting the dates? Or where do I mess up?

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)
4

4 回答 4

10

你的问题是你有一个字符串,但看起来像一个数字,你在导入过程中没有处理这个问题。R 不区分1993.11993.10。两者是同一个号码。因此,as.character(1993.10)返回"1993.1"。您需要使用格式化函数来确保在句点之后得到两位数,因为 toas.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应该以字符开头。

于 2015-11-12T14:18:14.313 回答
6

如果您真的只是想"Date"使用月份的第一天将其转换为类,那么 Roland 的解决方案似乎是最直接的,但还有其他一些考虑因素,例如您是否想要使用月末或者您是否真的想要代表年份-月份首先使用日期。

zoo 包有一个"yearmon"类,它可以直接表示年月而不将它们转换为日期,并且还有一个方法,该as.Date.yearmon方法有一个frac=参数,可用于指定月份中要转换的部分,如果你确实想要"Date"类。

首先,确保日期是字符串。问题中的输入显示 1993.10 作为输入之一,因此我们必须确保尾随零。(如果输入已经是带有尾随零的字符,那么这不是问题。我们在这里假设最坏的情况是假设数字,因此如果需要,我们需要将它们显式转换为带有尾随 0 的字符串。)现在使用as.yearmonwith格式"%Y.%m"。最后用于as.Date.yearmon转换为"Date"类。

也许这种方法的最大优点是我们可以将结果留在"yearmon"类中(即省略"as.Date"部分,例如,as.yearmon(sprintf("%.2f", dates))或者如果日期已经是字符串,,在then justdates.ch的情况下带有尾随 0 ,它真正代表了你的有更好的,因为这一天并不真正有意义,因为它一开始就不在那里。 对象可以按预期的方式绘制和排序。"1993.10"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"

或者如果测试输入如下所示:

dates.ch <- c("1993.07", "1993.08", "1993.09", "1993.10", "1993.11", "1993.12") # input 

as.Date(as.yearmon(dates.ch, "%Y.%m"))

as.Date(as.yearmon(dates.ch, "%Y.%m"), frac = 1)
于 2015-11-12T14:22:56.623 回答
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")

解释:

paste0paste是在粘贴的元素之间不插入空格的简写版本。
in formatC,digits指定小数点后你想要的位数(在我们的例子中,我们想要 2. format 告诉 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"
于 2015-11-12T14:16:53.550 回答
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
于 2015-11-12T14:17:30.543 回答