【问题标题】:as.Date from 'YYYY.mm' format [duplicate]as.Date 来自 'YYYY.mm' 格式 [重复]
【发布时间】:2016-02-13 21:28:36
【问题描述】:

我有一个数据框,其中日期存储为double,例如1993.09 1993.10 1993.11 1993.12

我想把它转换成日期格式'%Y %m %d'(总是有天1)。

据我了解,as.Date() 想要一个字符串输入。但是,由于某种原因,当我将日期转换为字符串 sapply(dates, as.character) 时,一个后面的零消失了,实际上将 10 月转换为 1 月,从而导致每年有两个 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"

有没有更直接的转换日期的方法?或者我哪里搞砸了?

输入:

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)

【问题讨论】:

    标签: r date as.date


    【解决方案1】:

    使用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 的简写版本,不会在粘贴的元素之间插入空格。
    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"
    

    【讨论】:

      【解决方案2】:

      您需要对字符串进行一些摆弄。最明显的方法(对我来说*)是用零“填充”值的右侧。

      * 这是一个很大的警告

      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
      

      【讨论】:

        【解决方案3】:

        您的问题是您有一个字符串,但看起来像一个数字,而您在导入过程中没有注意这一点。 R 不区分1993.11993.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 应该以字符开头。

        【讨论】:

        • dputx &lt;- c(1993.09, 1993.1, 1993.11, 1993.12),但您的解决方案仍然有效。
        • @DavidArenburg R 不在乎你是给它1993.1 还是1993.10。这是一个相同的替身。
        【解决方案4】:

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

        zoo 包有一个"yearmon" 类,它可以直接表示年月而不将它们转换为日期,还有一个as.Date.yearmon 方法,它有一个frac= 参数,可用于指定通过的方式的分数如果您确实想要 "Date" 课程,则要转换到的月份。

        首先,确保日期是字符串。问题中的输入显示 1993.10 作为输入之一,因此我们必须确保尾随零。 (如果输入已经是带有尾随零的字符,那么这不是问题。我们在这里假设最坏的情况是假设数字,因此如果需要,我们需要将它们显式转换为带有尾随 0 的字符串。)现在使用 @ 987654326@ 格式为"%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" 对象可以被绘制和排序预期的方式。

        这是使用"yearmon" 转换为"Date" 类:

        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)
        

        【讨论】:

        • 对每月最后一天的解决方案投赞成票。
        • 因为我记得 zoo 包裹,请给我点赞,我忘了!
        • @SerbanTanasa 他写了动物园包...
        • 这样会很容易记住,然后:)
        猜你喜欢
        • 1970-01-01
        • 2012-11-03
        • 2020-04-29
        • 1970-01-01
        • 2020-08-09
        • 2021-08-21
        • 2017-01-19
        • 2021-11-21
        • 2021-07-08
        相关资源
        最近更新 更多